简体   繁体   English

类型参数继承的通用类型转换

[英]Generic Type conversion on type parameter inheritance

Given the following code: 给出以下代码:

namespace sample
{
    class a { }

    class b : a { }

    public class wrapper<T> { }

    class test
    {
        void test1()
        {
            wrapper<a> y = new wrapper<b>();
            //Error 11  Cannot implicitly convert type 'sample.wrapper<sample.b>' to 'sample.wrapper<sample.a>' 
        }
    }
}

Logically speaking, a since b is a , a wrapper<b> is a wrapper<a> . 从逻辑上讲,由于ba ,所以wrapper<b>wrapper<a> Then why I can't make this conversion, or how can I make it? 那为什么不能进行这种转换,或者我怎么进行呢?

Thanks. 谢谢。

since b is a, a wrapper<b> is a wrapper<a> 因为b是a,所以wrapper<b>wrapper<a>

Well, this is not true for .NET generic classes, they can't be co-variant. 嗯,.NET泛型类并非如此,它们不能是协变的。 You can achieve something similar using interface covariance: 您可以使用接口协方差实现类似的操作:

class a { }
class b : a { }

public interface Iwrapper<out T> { }
public class wrapper<T> : Iwrapper<T> {}

class test
{
    void test1()
    {
        Iwrapper<a> y = new wrapper<b>();
    }
}

This is a matter of covariance. 这是协方差问题。

Class b is an a , but wrapper<b> is not a wrapper<a> . ba ,但是wrapper<b>不是wrapper<a>

You can use C# 4's covariance syntax to allow it like so: 您可以使用C#4的协方差语法来允许它,如下所示:

public interface IWrapper<out T> { ... }

public class Wrapper<T> : IWrapper<T> { ... }

This will instruct the CLR to see Wrapper<B> as a Wrapper<A> . 这将指示CLR将Wrapper<B>视为Wrapper<A>

(For the record: C# has capitalization conventions; class names are Pascal-cased). (记录:C#具有大写约定;类名使用Pascal大小写)。

Lets do a scenario. 让我们做一个场景。 Lets call the class a Mammal , the class b Dog , and lets say that the wrapper<T> class is List<T> 让我们将类a Mammal ,将类称为b Dog ,并说wrapper<T>类为List<T>

See what happens in this code 看看这段代码会发生什么

List<Dog> dogs = new List<Dog>();  //create a list of dogs
List<Mammal> mammals = dogs;   //reference it as a list of mammals

Cat tabby = new Cat();
mammals.Add(tabby)   // adds a cat to a list of dogs (!!?!)

Dog woofer = dogs.First(); //returns our tabby
woofer.Bark();  // and now we have a cat that speaks foreign languages

(Paraphrase of my answer on How to store base class children in a dictionary? ) (我对“ 如何在字典中存储基层孩子的答案”的部分措辞)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM