1

可能重复:
为什么 C# 泛型不能像在 C++ 模板中那样从泛型类型参数之一派生?
继承其泛型类型的泛型类

我希望能够做这样的事情,只有在 C# 中:

template<class MyClass>
class MockComposite : MyClass
{

};

上面的类继承自指定的类型。MyClass 是一个基本类型,这就是我想要这种行为的原因。我希望能够使用派生自 MyClass 的类来实例化这个对象。

我知道您不能在 C# 中使用模板,但是有没有办法获得我想要的行为而不必为每种不同类型的对象编写一个新类?

编辑 - 我希望能够实例化一个对象,该对象将测试任何类的行为,只要该类派生自指定类型 - 'MyClass'。

4

2 回答 2

1

在 C# 中,您有泛型的概念。以下代码等效于您的 C++ 代码:

class MockComposite<T> : T
    where T : MyClass
{
}

不幸的是,它是无效的。您将收到以下编译错误:

无法从“T”派生,因为它是类型参数

在 C# 中,您通常会使用组合而不是继承来解决此问题。

在这种情况下,组合意味着两件事之一:

  1. 您的类仍然具有通用参数,但不会尝试从中派生。此外,它有new约束,这意味着泛型参数需要有一个默认构造函数:

    class MockComposite<T>
        where T : MyClass, new()
    {
        T _toTest;
    
        public MockComposite()
        {
            _toTest = new T();
        }
    }
    

    这意味着您可以像这样实例化模拟类:var mock = new MockComposite<ClassA>();无需在ClassA模拟类之外创建实例。

    class MockComposite
    {
        MyClass _toTest;
    
        public MockComposite(MyClass toTest)
        {
            _toTest = toTest;
        }
    }
    

    这意味着您必须像这样实例化模拟类:var mock = new MockComposite(new ClassA());

于 2012-08-28T14:54:51.723 回答
0

这在 C# 中根本不可能。但这是试图将一种语言用作另一种不同的语言的情况。在 C++ 中,这种模式有其用途。您可以在 C# 中完成相同的事情,但使用不同的技术。

也许这会帮助你:

class Myclass
{
}

class ChildClass : MyClass
{
}

class MockComposite<T> where T : MyClass
{
    public MockComposite(T objectToTest) { ... }
}

在这里,您可以传递派生自MyClassinto的任何类CompositeTester<>。这和你的代码最大的区别是,这里你需要传入真实的现有非泛型类,这些类继承MyClass. 您正在尝试进行一般继承,这是不可能的。

在 C++ 中,这基本上就像在做:

class Myclass
{
};

class ChildClass : MyClass
{
};

template<typename T>
class MockComposite
{
public:
    MockComposite(const T& objectToTest) { ... }
};

C# 泛型可能看起来有点像 C++ 模板,但这是一个完全不同的想法。虽然 C++ 模板让您非常灵活,几乎可以像宏一样,但泛型在类型方面仍然相当紧凑。你不能用一个你没有说它可以显式做的泛型类型做任何事情,因此像where T : MyClass. 通过指定,MockComposite.MockComposite可以T用作MyType.

于 2012-08-28T14:55:05.110 回答