在 C# 3.0 和 .NET 3.5 上,假设有一个接口:

public interface INameable
{
  string Name {get;}
}

以及许多实现该接口的不可变类。

我想要一个单一的扩展方法

public static T Rename<T>(this T obj) where T : INameable
{ 
  ...
}

返回原始对象的包装实例,仅更改名称,所有其他属性读取和方法调用都路由到原始对象。

如何为此获取通用包装类,而不为所有 INameable 实现类型实现它?你认为这可能吗?

有帮助吗?

解决方案

不,这是不可能的,除非 T 被限制为一个接口或一个所有成员均为虚拟的类,并且此约束不可能在编译时指定(尽管如果您对这种方法感到满意,您可以编写运行时检查)。

不能对任意类型执行此操作的原因是,如果您采用类型的对象 T 那么你必须返回一个可分配给的对象 T. 。如果我传递一个如下所示的对象......

public sealed class SomeClass : INameable
{
    public string Name { get; }
    public string Abc { get; }
}

...那么您就无法创建另一种可分配给的类型 SomeClass. 。不使用 Reflection.Emit 或任何其他方法,因为类型是密封的。

但是,如果您对我提到的限制感到满意,那么您可以使用 Castle DynamicProxy 框架之类的东西来创建一个类型,该类型代理传入的对象并拦截调用以根据需要进行转发或重新实现。

其他提示

嗯,是的,这是可能的,但它涉及在内存中生成代码。

您可以查看 Reflection.Emit 这里

请注意,它将涉及大量代码。

也就是说,如果我认为我理解正确的话。

以下是我认为你要求的内容:

SomeNameableObject a1 = new SomeNameableObject("ThisIsTheFirstName");
SomeNameableObject a2 = a1.Rename("ThisIsTheSecondName");
// a1 works, still has the name ThisIsTheFirstName
// a2 works, but everything is routed to a1,
//    except for the name, which is ThisIsTheSecondName

这是对的吗?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top