在仍然暴露其所有公共方法,属性和字段的同时包装类

时间:2013-11-20 10:30:48

标签: c# generics reflection

我正在尝试创建一个通用的包装类,它可以包装任何其他类并为其添加额外的功能。但是,与此同时,我希望能够在通常使用包装类的地方使用此包装器。目前我使用隐式转换工作正常。但是在理想的世界中,我希望包装类具有与包装类相同的公开方法和字段,就像在这段示例代码中一样:

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;运算符来操作字段内容而不是包装器。

2 个答案:

答案 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可以为您提供一个良好的起点。