I've got two generic base classes. The second generic class has a constraint on its parameter of the first class.
abstract class FirstClass<T> {...}
abstract class SecondClass<U> where U : FirstClass {...}
This does not work, because FirstClass is not defined. So I need to do this.
abstract class FirstClass<T> {...}
abstract class SecondClass<U, T> where U : FirstClass<T> {...}
Which works. However, this makes implementing these abstract classes ugly.
class SomeClass {...}
class MyFirstClass : FirstClass<SomeClass> {...}
class MySecondClass : SecondClass<MyFirstClass, SomeClass> {...}
This seems redundant to me because I'm specifying SomeClass twice. Is there a way to declare it in such a way that T from FirstClass is automatically the U for SecondClass. What I would really like this to look like is.
class SomeClass {...}
class MyFirstClass : FirstClass<SomeClass> {...}
class MySecondClass : SecondClass<MyFirstClass> {...}
While I doubt this exact scenario is possible, is there a cleaner what to do what I am trying to do?
Edit
Several people have suggested making an IFirstClass interface. But my definitions are closer to this.
class FirstClass<T>
{
public T MyObj { get; set; }
}
class SecondClass<U, T> where U : FirstClass<T>
{
U MyFirstClass { get; set; }
}
With an interface I cannot access MyFirstClass.MyObj from SecondClass. While I could create a object T MyObj { get; set; }
on IFirstClass, then use new
to hide it, silverlight throws a fit in the binding if I do this.
Abstract is used to define something that requires additional definition of functionality before it is considered "complete" (or concrete in Java-certification-test-terms). Generic means it's a class that can handle a wide variety of data types that you define when you instantiate the class.
A Generic class can have muliple type parameters.
We can first declare an abstract class that uses generics T . Our generic T could refer to any class (i.e. String , Double , Integer , etc.). This is declared when the AbstractJob class is referenced. These generics can be named anything; it doesn't have to be T .
Cannot Create Instances of Type Parameters. Cannot Declare Static Fields Whose Types are Type Parameters. Cannot Use Casts or instanceof With Parameterized Types. Cannot Create Arrays of Parameterized Types.
In my experience it is easiest to create non-generic interface to generic classes. It also solves the problem when you need to cast to the base class without knowing the generic type.
interface IFirstClass {...}
abstract class FirstClass<T> : IFirstClass {...}
abstract class SecondClass<T> where T : IFirstClass {...}
If you are actually using the generic type arguments to FirstClass
(as, from your edit, it sounds like you are), then no, what you're looking for is unfortunately not possible. The compiler does not differentiate between type arguments that are related and those that are not.
Create an interface that FirstClass implements. Then you can constrain SecondClass to the interface.
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