Generic type parameter constraint based on other type parameter in the same definition
I have type hierarchy defined like this:
interface IMyClass
{
}
interface IBase1<T>
{
}
interface IBase2<T>
{
}
interface IMyDerived1 : IBase1<IMyClass>
{
}
class Base1<T, U> : IBase1<T>
where U : IBase2<T>
{
}
class Base2<T, U> : IBase2<T>
where U : IBase1<T>
{
}
class Derived1<T, U> : Base1<T, U>, IMyDerived1
where T : IMyClass
where U : IBase2<T>
{
}
class Derived2<T, U&开发者_如何学JAVAgt; : Base2<T, U*>
where T : IMyClass
where U : IMyDerived1
{
}
but Visual Studio 2008 (.net 3.5 SP1) says that parameter U in parent specifier of Derived2 (marked with *) is not convertible to IBase1<T>
. Is this solvable?
EDIT:
It indeed looks like generics overuse but allows Base1,2 and Derived1,2 to apply operations on supplied types without a casts. Something like this:
class MyClass : IMyClass
{}
class MySpecific1 : Derived1<MyClass, MySpecific2>
{
// use inherited properties and methods of type MyClass here
// use properties of MySpecific2 returning MyClass without casts
}
class MySpecific2 : Derived2<MyClass, MySpecific1>
{
// use inherited properties and methods of type MyClass here
// use properties of MySpecific1 returning MyClass without casts
}
Probably this can be solved more elegantly with variance in .net4 but I'm stuck with 3.5 for now.
class Derived2<T, U>: Base2<T, U>
where T: IMyClass
where U: IMyDerived1, IBase1<T>
{
}
That hurt my head!
Having a look at it, the problem lies with this definition:
interface IMyDerived1 : IBase1<IMyClass>
{
}
You've specialised that generic implementation, and then attempted to use with generic arguments later on:
class Derived2<T, U> : Base2<T, U>
where T : IMyClass
where U : IMyDerived1
{
}
Which is invalid. Not sure if this is correct, but can you make either this change:
interface IMyDerived1<T> : IBase1<T>
{
}
class Derived2<T, U> : Base2<T, U>
where T : IMyClass
where U : IMyDerived1<T>
{
}
That's a complicated hierarchy you're designing there, what will be its use?
The problem is, in Derived2, T is not IMyClass, it could be some other class implementing this interface. In Base1, it is specified to be exactly IMyClass. Types with different generic arguments are not compatible in C# 3.0.
For me, this looks a bit like generic overuse. But I can't see the context.
精彩评论