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 TClass is a class, why isnt T a 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<T>()
where T : TClass
{
FuncA<T>();
FuncB<T>();
}
}
EDIT:
This actually works. Eric Lippert made me think, thanks.
Since T is a TClass and TClass is a TAnotherType, T is actually 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>();
}
}
Since
T
is aTClass
andTClass
is a class, why isn'tT
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/
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With