0

我在以下铸造方面遇到了一些问题:

    class A 
    { 
    }

    class B : A 
    {
    }

    class C<T> where T : A
    {
        protected T property { get; set; }
    }

    class D : C<B> 
    {
    }

    class MainClass
    {
        public static void Main (string[] args)
        {
            C<A> x = new D();
            // Error CS0029: Cannot implicitly convert type `SampleApp.D' to `SampleApp.C<SampleApp.A>' (CS0029) (SampleApp)
        }
    }

我不明白为什么这会失败,因为它DC<A>实现C<B>, 和B : A. 任何解决方法?

4

3 回答 3

2

如果可以使用 C# 4.0,则可以编写以下代码。

class A { }
class B : A {}

interface IC<out T> {}
class C<T> :IC<T> where T : A { protected T property { get; set; }  }

class D : C<B> {}

class MainClass {
    public static void Main()
    {
        IC<A> x = new D();
    }
}
于 2012-11-09T22:34:37.927 回答
1

让我们将您的类命名Animal为 for ABarkerforBDogfor D

其实C<Animal>Dog : C<Barker>. 假设您有可能Me的类型T和赋值的公共属性:

C<Animal> a = new Dog();
a.Me = Elephant; // where Elephant inherited from Animal

哎呀!Dog用 参数化Barker。你见过吠叫的大象吗?

您需要声明一些协变接口,以允许将使用更多派生类型参数实例化的类分配C<Barker>给使用较少派生类型参数实例化的对象C<Animal>。您可以使用空接口,如@NickW 建议的那样,但您将无法对该接口的实例执行某些操作(它是空的!)。所以,让我们做这样的事情:

interface IC<out T>
    where T : Animal
{
    IEnumerable<T> Parents(); // IEnumerable is covariant
    T Me { get; } // no setter
}

class C<T> : IC<T>
    where T: Animal
{
    // implementation
}

class D : C<Barker>
{
    // implementation
}

上述情况仍然是不可能的,但现在你可以

IC<Animal> a = new Dog();
foreach(var parent in a.Parents)
     Console.WriteLine(parent);

Console.WriteLine(a.Me);
于 2012-11-09T22:28:10.977 回答
-1

你不能这样做,因为泛型实际上是模板,它们的行为不像你想用它们做的那样。让我通过这个来告诉你:

当您说它"C<A>"意味着 a 的泛型类"parameter""A"。但是当你说它"D"的意思时"D"

因此,通过 A 的参数,D 不等于泛型类。您可以在两种类型的 ToString 函数的结果中简单地看到它(通过使用 typeof)。

希望能帮助到你

干杯

于 2012-11-09T22:22:13.620 回答