使用泛型类型保持代码组织

时间:2011-12-07 19:51:12

标签: c# generics reflection dynamic

我喜欢在编程时保持分开。这是我相信继承很重要的原因之一。

我正在使用一个由我无法修改的类组成的dll文件。 dll文件包含ClassA来说明我的例子。

class Program
{
    static void Main(string[] args)
    {
        ClassA object1 = new ClassA();

        SomeMethod<ClassA>(object1 ); // error because " a does not implement ITemp"
    }

    static T SomeMethod<T>(T input)
        where T:ITemp // make sure input has a method MyCustomMethod
    {

        input.MyCustomMethod();

        return input;
    }
     // create this interface so that compiler does not complain when
     // calling MyCustomMethod in method above

    interface ITemp
    {
        void MyCustomMethod();
    }

}


// classA is a sealed class in a dll file that I cannot modify
public class ClassA
{
    public void MyCustomMethod()
    {

    }
}

如果object1实现ITemp接口,为什么会出错? object1的方法是MyCustomMethod()

我知道我可以使用反射来解决这个问题,但我喜欢保持代码清洁。我也想避免使用动态类型。

2 个答案:

答案 0 :(得分:4)

ClassA没有实现ITemp接口。仅仅因为它具有与ITemp接口中的方法具有相同名称和签名的方法并不意味着它实现了该接口。需要声明该类以明确地实现它。

由于你无法扩展ClassA,我能想到的最好的事情就是用适配器类型包装它:

public ClassB : ITemp {
    protected ClassA classAInstance;

    public ClassB( ClassA obj ) {
        classAInstance = obj;
    }

    public void MyCustomMethod() {
        classAInstance.MyCustomMethod();
    }
}

然后在你的主要方法中:

static void Main(string[] args)
{
    ClassA object1 = new ClassA();

    SomeMethod<ClassB>(new ClassB(object1));
}

答案 1 :(得分:1)

您正在尝试使用duck typing。 C#在dynamic类型之外通常不支持。 ClassA需要实现接口,正如您所指出的那样,它不会被实现。你可以用代理包装类,但这可能是也可能不是一个好主意。