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>();
    }
}

c#泛型约束传播

既然T是一个TClass, TClass是一个类,为什么T不是一个类?

前提1:"Bob Smith"是一个专有名词。

前提2:"专有名称"是一个三个单词的句子片段。

结论:因此"Bob Smith"是一个三个单词的句子片段。

那个逻辑显然是不正确的。

前提1:TTClass

前提2:TClass是一个类

结论:T是一个类。

由于同样的原因,逻辑是不正确的。

在这两种情况下,我们都用"is"来表示两个前提中完全不同的东西。在第一个前提中,"is"用来表示"这两个事物之间有某种关系"。在第二个前提中,"is"用于表示"这一事物具有特定的特征"。

您可以通过简单地替换TTClass来更直接地看到您的逻辑是错误的:

前提1:intSystem.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。请不要试图解释奇怪的事情,只用一个例子来证明。