Why Do I need to redeclare type constraint in generic subclass
Recently I tried to create a generic subclass by implementing a generic interface.
public interface IModule<T> where T : DataBean { ..... }
public class Module<T> : IModule<T> where T : DataBean { .... }
It seems I can't rely on any of T's restrictions as were defined in the base interface, and I need to re-declare them myself.
MSDN just provided:
When using the subcla开发者_StackOverflow社区ss generic type parameters, you must repeat any constraints stipulated at the base class level at the subclass level. For example, derivation constraint
Why isn't it possible to infer the constraints from the base class/interface ?
I can't come up with any reason that the c# couldn't theoretically copy over constraints. But the documented behavior of making us copy (or augment) them explicitly seems to be the simplest way for usability.
public class A{}
public class B : A {}
public class X<T> where T: A {}
public class Y<T> : X<T> where T: B { }
In the above, note that I did not have to explicty copy over the constraint on Y<T>
, because a B
is always an A
.
Now lets look at what happens if the "compiler automatically copies over constraints". Let's say I define Y<T>
without constraints and the compiler places them automatically. I use Y<T>
in lots of code. Then I change the constraints on the declaration of X<T>
to include some new interface.
The compiler errors for changing the declaration of X<T>
are at the sites where I use Y<T>
!
With the way the c# compiler currently works, the compiler errors are at the usages of X<T>
, as I would expect if I change it in a breaking way.
So while it would be convenient in some scenarios, it would also be somewhat confusing in others. While both are valid approaches, I would assume (note that I'm not able to read the minds of the c# design team) that it was a judgement call and not a purely technical one.
I say "not purely technical", but I can certainly imagine some interface scenarios where it would be somewhat simpler to verify that all constraints are met, rather than produce the simplest constraint that meets all required inherited constraints.
Standard C# team wisdom. Declarations should be self-documenting. And most of all, a change in one type declaration should not alter the behavior of an unrelated other type without generating a diagnostic. The -100 points principle put into design is another take on that.
The constranints on the interface are too vauge to tell the compiler what constraints the Module class should have. For example, the Module class could have a constraint on a super-class (inherited class) of DataBean.
I don't know the wisdom of the C# designers. Because the constraints can be different, I think a decision was made to have the developer explicitly declare the constraint rather than having the compiler make assumptions.
精彩评论