想要一个通用的Wrapper类

时间:2011-01-12 14:35:20

标签: c# .net class inheritance wrapper

为了继承目的,我想拥有以下课程,我自己不能写,可用:

class Wrapper<G> : G
{
    public Wrapper(G base);
    protected G GetBase();
}

它将继承G的所有成员,并且这些成员的所有用法都将被重定向到构造期间提供的G.

在技术上是否可以将此功能添加到C#等语言中?

我想用它的主要用例是:

    class Wrapper<G> : G
    {
        public Wrapper(G g);
    }

    class IGraphNode<G> where G : IGraphNode<G>
    {
        IEnumerable<G> ForwardNodes();
        IEnumerable<G> BackwardNodes();
    }

    //Reverses the direction of the graph.
    class Reverse<G> : Wrapper<G> where G : IGraphNode<G>
    {
        public Reverse(G g)
            : base(g)
        { }

        IEnumerable<G> ForwardNodes()
        {
            return base.BackwardNodes();
        }

        IEnumerable<G> BackwardNodes()
        {
            return base.ForwardNodes();
        }
    }

4 个答案:

答案 0 :(得分:1)

不确定这是否是您想要的,但您可以使用DynamicProxy在运行时创建包装器对象,并根据需要拦截方法和属性调用。

答案 1 :(得分:0)

我认为这存在于Ruby中,忘记了它的名称。 C#不支持此功能。是否可以在C#中添加此功能?当然,如果你能说服.Net和C#团队实现这个......但我怀疑他们会这样做。

答案 2 :(得分:0)

这不是用于扩展的内容吗?

public static class MyStringExtensions
{
    public static string Add1ToString(this string myString)
    {
        myString += "1";
        return myString;
    }
}

在其他课程中,您现在可以使用以下内容:

using YourNamespaceOfTheExtensionMethods;

public class OtherClass
{
    public string DoSomething()
    {
        string someString = "Hello";
        return someString.Add1ToString();
    }
}

我使用了string作为示例,但如果您愿意,可以扩展Object

答案 3 :(得分:0)

你可以用反射做到这一点。但你的目标到底是什么?要装饰一个类,还是创建用它来做事的工具?以您希望的方式扩展类的现有实例似乎有风险,因为您不会创建基类的新实例,并且使用该对象的代码将不会意识到这一点。也就是说,属性可以只更改新对象或其扩展的其他对象,并且语法中的确切功能将是未知的。

我认为它(通常)更加透明,例如,

class Wrapper<G> where G: SomeType
{
    public G Base;
    public Wrapper(G g) {
        Base = g;
    }

    // methods to do stuff with object supplied at construction
}

你可以在没有where的情况下做到这一点,但我想不出很多理由,为什么你不关心基本类型是什么。

如果你真的想要创建一个具有新属性的新类,并继承现有类中的数据,我认为你可能会努力尝试,因为这并不是真的有意义:两个对象都不会以明智的方式更长时间的约束。也就是说,对基类属性的更改会影响与扩展属性更改不同的对象。如果你在这个例子中有MyWrapper.Base中的属性,那么这恰好会发生什么,但是如果这实际上是你的目标,那么在概念上更合理地保持对基础的对象引用是分开的。否则,使用您的扩展程序对象的客户将无法理解这一点,您很容易就会知道为什么您的代码无法正常运行...

如果要创建一个扩展内容的新对象,并以某种透明的方式复制现有对象的属性,请执行以下操作:

class Wrapper<G>: G
{
    public Wrapper(G g) {
        // add memberwise copy function
    }
    .. more properties
}

Wrapper<SomeType> newWrapper = Wrapper<SomeType>(someOtherObject);

..就像你如何从现有列表中创建新列表一样。