我可以
public class MyGenericClass : DL
//but i cannot do
public class MyGenericClass <T> : T
Run Code Online (Sandbox Code Playgroud)
我怎么做第二个?如果我不能那样做,我该怎么办呢
public class MyGenericClass <T>
{
T obj;
//have all MyGenericClass.XYZ call obj.XYZ
}
Run Code Online (Sandbox Code Playgroud)
这是不可能的,因为根据T的类型,MyGenericClass的公共接口会发生变化.
如果你有很多不同的类都暴露了相同的接口,你可以声明MyGenericClass来公开那个接口,并在所有函数的实现中委托调用obj
你可以做类似的事情
public interface IXyzable { void xyz(); }
public class MyGenericClass<T> : IXyzable where T : IXyzable {
T obj;
public void xyz() {
obj.xyz();
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:现在我明白了这个问题
具体问题,为什么你不能这样做:
public class MyGenericClass<T> : T
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
public class MyGenericClass<T>
{
T obj;
}
Run Code Online (Sandbox Code Playgroud)
原因是CLR喜欢能够为MyGenericClass编译单个版本的代码,该代码适用于为T指定的任何引用类型.
它可以为第二种情况下做到这一点,因为它可以悄悄地代替T用object,并插入相应的强制类型转换,大致相当于:
public class MyGenericClass
{
object obj;
}
Run Code Online (Sandbox Code Playgroud)
但对于继承版本,该技巧不起作用.
此外,通过界面约束无法描述许多有用的设施.从类型继承时,除了调用方法之外,您还可以做很多事情 - 您也可以覆盖它们.考虑这个假设的例子:
class MyBase
{
public virtual void MyVirtual() { }
}
class MyGenericDerived<T> : T
{
public override void MyVirtual()
{
Console.WriteLine("Overridden!");
}
}
MyBase obj = new MyGenericDerived<MyBase>();
obj.MyVirtual();
Run Code Online (Sandbox Code Playgroud)
我想要做的就是"混合",其中MyGenericDerived提供虚拟函数的定义,无论它应用于何种基础.但编译器如何知道T将有一个可以覆盖的名为MyVirtual的方法?我需要对T进行约束.如何通过接口表达?不可能.一旦允许从类型参数继承,使用接口来描述约束就不是一个合适的解决方案.这就是今天语言中不存在的另一个原因.
| 归档时间: |
|
| 查看次数: |
33907 次 |
| 最近记录: |