c#泛型约束传播
本文关键字:约束传播 泛型 | 更新日期: 2023-09-27 18:13:33
这个例子是对实际问题的简化,但是我怎样才能使它编译呢?我希望泛型约束能够传播。
既然T是一个TClass而TClass是一个类,为什么T不是一个类?
public class MyClass<TClass> where TClass : class
{
public void FuncA<Ta>() where Ta : class
{
}
public void FuncB<Tb>() where Tb : TClass
{
}
public void Func<T>()
where T : TClass
{
FuncA<T>();
FuncB<T>();
}
}
编辑:
这确实有效。Eric Lippert让我思考,谢谢。
因为T是一个TClass,而TClass是一个TAnotherType,所以T实际上是TAnotherType。
public class MyClass<TClass, TAnotherType> where TClass : TAnotherType
{
public void FuncA<Ta>() where Ta : TClass
{
}
public void FuncB<Tb>() where Tb : TAnotherType
{
}
public void Func<T>()
where T : TClass
{
FuncA<T>();
FuncB<T>();
}
}
既然
T
是一个TClass
,TClass
是一个类,为什么T
不是一个类?
前提1:"Bob Smith"是一个专有名词。
前提2:"专有名称"是一个三个单词的句子片段。
结论:因此"Bob Smith"是一个三个单词的句子片段。
那个逻辑显然是不正确的。
前提1:T
是TClass
前提2:TClass
是一个类
结论:T
是一个类。
由于同样的原因,逻辑是不正确的。
在这两种情况下,我们都用"is"来表示两个前提中完全不同的东西。在第一个前提中,"is"用来表示"这两个事物之间有某种关系"。在第二个前提中,"is"用于表示"这一事物具有特定的特征"。
您可以通过简单地替换T
和TClass
来更直接地看到您的逻辑是错误的:
前提1:int
是System.ValueType
('is'表示'有子类关系')
前提2:System.ValueType
是一个类
('is'表示'具有特定的属性,即通过引用复制)
结论:int
是一个类。
又一次,我们得出了一个错误的结论,因为"is"有两种不一致的用法。
另一个例子:
前提1:有汉堡包总比没有好。
前提2:没有什么比一块好牛排更好。
结论:就及物性而言,汉堡包比牛排好。
最后,关于这个主题的更多想法,请参阅我最近的文章:
http://ericlippert.com/2011/09/19/inheritance-and-representation/问题是T
不一定是引用类型。考虑:
MyClass<IFormattable> foo = new MyClass<IFormattable>();
MyClass.Func<int>();
这将尝试调用FuncA<int>
,但int
不遵守: class
的约束。
: class
约束也添加到Func<T>
:
public void Func<T>() where T : class, TClass
要编译这个,请执行;
public void Func<T>()
where T :class, TClass
{
FuncA<T>();
FuncB<T>();
}
因为FunA的input只是一个类而不是特殊的类
我不确定以下是代码中的错别字还是复制/粘贴更改(为了简化):
public void FuncA<Ta>() where Ta : class //TClass instead of class?
{
}
看起来你只是好奇为什么你不能这样做。你对这样的工作示例不感兴趣:
public class MyClass<TClass> where TClass : class
{
public void FuncA<Ta>() where Ta : class
{
}
public void FuncB<Tb>() where Tb : TClass
{
}
public void Func()
{
FuncA<TClass>();
FuncB<TClass>();
}
}
你们都说T: TClass和TClass: class并不意味着T: class。如果我给你:
public MyClass<TClass> where TClass : class
{
public void MyFunc<T>() where T : TClass
{
// who cares ?
}
}
你能提供一个例子,你使用类型T不是一个类,因为我真的不明白为什么T: TClass和TClass: class不暗示T: class。请不要试图解释奇怪的事情,只用一个例子来证明。