C# generics contraints propagation

后端 未结 5 1336
佛祖请我去吃肉
佛祖请我去吃肉 2021-02-10 06:11

This example is a simplification of the real problem, but how can I get this to compile? I would expect the generics constraints to propagate.

Since T is a TClass and TC

相关标签:
5条回答
  • 2021-02-10 06:24

    Looks like you're just curious why you can't do so. And you're not interested in working example like this:

    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>();
        }
    }
    
    0 讨论(0)
  • 2021-02-10 06:34

    Since T is a TClass and TClass is a class, why isn't T a class?

    Premise 1: "Bob Smith" is a proper name.

    Premise 2: "A proper name" is a three word sentence fragment.

    Conclusion: Therefore "Bob Smith" is a three word sentence fragment.

    That logic is obviously not correct.

    Premise 1: T is a TClass

    Premise 2 : TClass is a class

    Conclusion: Therefore T is a class.

    That logic is incorrect for the same reason.

    In both cases we are using "is" to mean two completely different things in the two premises. In the first premise, "is" is used to mean "these two things have the is-a-kind-of relationship between them". In the second premise, "is" is used to mean "this one thing possesses a particular characteristic".

    You can see that your logic is wrong more directly by simply substituting in for T and TClass:

    Premise 1: int is a System.ValueType

    ('is' means 'has a subclassing relationship')

    Premise 2 : System.ValueType is a class

    ('is' means 'has a particular property, namely, being copied by reference)

    Conclusion: Therefore int is a class.

    And again, we come up with an incorrect conclusion because "is" is used in two inconsistent ways.

    Another example:

    Premise 1: A hamburger is better than nothing.

    Premise 2: Nothing is better than a good steak.

    Conclusion: A hamburger is better than a good steak, by transitivity.

    Finally, for more thoughts on this topic, see my recent article:

    http://ericlippert.com/2011/09/19/inheritance-and-representation/

    0 讨论(0)
  • 2021-02-10 06:35

    I'm not sure if the following is a typo in your code or in your copy/paste alteration (for simplification):

    public void FuncA<Ta>() where Ta : class //TClass instead of class?
    {
    }
    
    0 讨论(0)
  • 2021-02-10 06:39

    For compiling this do;

    public void Func<T>()
        where T :class, TClass
    {
        FuncA<T>();
        FuncB<T>();
    }
    

    because input of FunA is just a class not special class.

    0 讨论(0)
  • 2021-02-10 06:42

    The problem is that T doesn't have to be a reference type. Consider:

    MyClass<IFormattable> foo = new MyClass<IFormattable>();
    MyClass.Func<int>();
    

    That would try to call FuncA<int> but int doesn't obey the : class constraint.

    So basically you need to add the : class constraint to Func<T> as well:

    public void Func<T>() where T : class, TClass
    
    0 讨论(0)
提交回复
热议问题