我一直在玩界面和泛型。
我想要的是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();
不起作用!
答案 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>
,但反之亦然。