我正在尝试创建一个通用的包装类,它可以包装任何其他类并为其添加额外的功能。但是,与此同时,我希望能够在通常使用包装类的地方使用此包装器。目前我使用隐式转换工作正常。但是在理想的世界中,我希望包装类具有与包装类相同的公开方法和字段,就像在这段示例代码中一样:
class Foo
{
public int Bar() { return 5; }
}
class Wrapper<T>
{
private T contents;
public void ExtraFunctionality() { }
public static implicit operator T(Wrapper<T> w) { return w.contents; }
}
Foo f = new Foo();
Wrapper<Foo> w = new Wrapper<Foo>(foo);
int y = w.Bar();
我可以使用一些古老的巫术,反思或其他技巧来实现这一目标吗?
注意:在C ++中我只是重载 - &gt;运算符来操作字段内容而不是包装器。
答案 0 :(得分:1)
我不推荐这个,但是因为你提到了巫术......你可以使用DynamicObject
进行动态输入。包装器尝试处理请求的方法。如果不能,则将调用转发给底层包装对象:
class DynamicWrapper : DynamicObject
{
private readonly object _contents;
public DynamicWrapper(object obj)
{
_contents = obj;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
if (binder.Name == "ExtraFunctionality")
{
// extra functionality
return true;
}
var method = _contents.GetType()
.GetRuntimeMethods()
.FirstOrDefault(m => m.Name == binder.Name);
if (method == null)
{
result = null;
return false;
}
result = method.Invoke(_contents, args);
return true;
}
}
修改强>:
没关系,我只是注意到你想在通常使用包装类型的实例的地方使用这个实例。
您必须将字段/属性/变量声明更改为dynamic
才能使用它。
答案 1 :(得分:0)
您可以使用System.Reflection.Emit命名空间中的类动态生成类型。这个link可以为您提供一个良好的起点。