C # generic types

I use three classes in my library:

public abstract class Base<TFirst, TSecond>
{
    public Base()
    {
      // actions with ID and Data of TFirst and TSecond
    }
}

public abstract class First<TFirstID, TFirstData>
{
    public TFirstID ID {get; set;}
    public TFirstData Data {get; set;}
}

public abstract class Second<TSecondID, TSecondData>
{
    public TSecondID ID {get; set;}
    public TSecondData Data {get; set;}
}

How can I indicate that TFirst should inherit from First and TSecond, should inherit from Second, without using common types for ID and Data in Base?

Like this:

public abstract class Base<TFirst, TSecond>
    where TFirst : First // without generic-types
...

Edit: In the First, Second classes, I use TFirstID and TSecondID for the properties. In the Base class, I use these properties.

+5
source share
5 answers

This can be tricky if they depend on signatures with these elements. I would suggest that I create an interface or an abstract base without type signatures. The interface is more likely.

+1
source

, :

public abstract class Base<TFirst, TSecond>
    where TFirst : First
{
    static Base()
    {
        if(!typeof(TFirst).IsGenericType || 
            typeof(TFirst).GetGenericTypeDefinition() != typeof(First<,>))
            throw new ArgumentException("TFirst");
    }
}

public abstract class First { }
public abstract class First<TFirstID, TFirstData> : First
{
}

First (IFirst).

- , .

+6

(non-generic) First<TFirstID, TFirstData> , :

public abstract class First{}

public abstract class First<TFirstID, TFirstData>
    : First
{
}

where TFirst : First . , , . , , - .

+2

, First Second , :

public interface IFirst 
{
}

public abstract class First<TFirstID, TFirstData> : IFirst
{
}

, IFirst

public abstract class Base<TFirst, TSecond>
   where TFirst : IFirst
+2

, , ; , .

- , , , :

public abstract class Base<TFirst, TSecond>
{
    public Base()
    {
        if(!typeof(TFirst).IsAssignableFrom(typeof(First))
            throw new InvalidOperationException("TFirst must derive from First.");
        if(!typeof(TSecond).IsAssignableFrom(typeof(Second))
            throw new InvalidOperationException("TSecond must derive from Second.");
    }
}

The above code is a serious smell of code. The whole family of pedigrees is to allow the class to work with many different inner classes, allowing the compiler to make sure that the types of parameters used are such that the common class can work with them. And besides, you should still be able to refer to the First and Second namespace (which I assume is the reason why you cannot use them as type parameters in the first place).

0
source

All Articles