C#通用速记和上传

时间:2016-05-24 20:33:09

标签: c# generics

我一直在玩界面和泛型。

我想要的是Foo<T>Foo<T, int>的简写这是明智的吗?以下是一种可以接受的方式吗?

using System.Diagnostics;

namespace MyNamespace
{
    public class Foo<T> : Foo<T, int> where T : class
    {
    }

    public class Foo<T, U> where T : class
    {
        public void Bar()
        {
            Debug.WriteLine("this: " + GetType().Name + ", T: " + typeof(T).Name + ", U: " + typeof(U).Name);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var fooT = new Foo<string>();
            var fooTU = new Foo<string, int>();

            fooT.Bar();
            fooTU.Bar(); 
        }
    }
}

我的实际问题是......是否可以向上(向下?)从Foo<T, int>投射到Foo<T>,其中T是同一类型。说这个甚至是有意义的,还是这与co / contravariance有关(这仍然是我的意思)?

对我来说,一个有点无知的人,在这个例子中Foo<string>Foo<string, int>是相同的类型,但当然((Foo<string>) fooTU).Bar();不起作用!

3 个答案:

答案 0 :(得分:3)

  

我的实际问题是......是否可以向上(向下?)从Foo<T, int>投射到Foo<T>,其中T是相同的类型。说这个甚至是有意义的,还是这与co / contravariance有关(这仍然是我的意思)?

如果实际对象的类型为Foo<string, int>,则可以从Foo<string>投射到Foo<T> 。它们具有相同名称的事实在这里完全无关紧要,所以让我们改变:

class Foo<T, U> {}
class Bar<T> : Foo<T, int>

现在:

Foo<string, int> foo = new Foo<string, int>();
Bar<string> bar = (Bar<string>) foo; // Bang, throws

可是:

Foo<string, int> foo = new Bar<string>();
Bar<string> bar = (Bar<string>) foo; // This is fine

仿制药在这里非常无关紧要,真的......这是正常的铸造规则。

答案 1 :(得分:1)

  

是否可以从Foo<T, int>升级为Foo<T>,其中T是相同的类型。

不安全 - 就像从Animal投射到Dog - 它可能dog,但是如果它不是你要去Foo<string, int>在运行时获得异常。

由于同样的原因,您也无法使用Foo<string>并将其视为{{1}}。

答案 2 :(得分:1)

  

在这个例子中,Foo和Foo是相同的类型

这是不正确的。 Foo<T>Foo<T,int>,但Foo<T,int>不一定是Foo<T>。这就是为什么你可以从Foo<T>投射到Foo<T,int>,但反之亦然。