C #: operator for generic types with inheritance

I have a problem with the is operator comparing generic types.

 public interface ISomeInterface<T> where T : SomeBaseClass{
 }

 public class SomeClass : SomeBaseClass{
 }

Now we want to check the type with the operator. We have an instance of the implementation interface of the ISomeInterface class.

Unfortunately, we face the following problem:

 // someObject is an Instance of a class implementing interface ISomeInterface<SomeClass>
 bool isSomeBaseClass = someObject is ISomeInterface<SomeBaseClass>; // false
 bool isSomeClass = someObject is ISomeInterface<SomeClass>; // true

Is it possible to check the type of a type variable?

Thanks in advance, Tobi

+3
source share
4 answers

This is called general covariance and is supported in C # 4.0. You can mark a general parameter Tusing the keyword out:

public interface ISomeInterface<out T> where T : SomeBaseClass

However, this is a limitation. The parameter Tcan only be displayed as a return type of methods in the interface.

, .

+8

, in out:

public interface ISomeInterface<in T> where T : SomeBaseClass{

}

:

public interface ISomeInterface<out T> where T : SomeBaseClass{

}

, in T , out, T .

:

, X<S> X<B>.

:

, X<B> X<S>.

- S - , B - .


, , # 4.0, .

class Stack<T>{
   int i;
   T[] array = new T[1000];
   public void Push(T element){
       array[i++] = element;
   }
}

class BaseClass{
}

class SubClass : BaseClass{
}

Infact , , Stack :

interface IPushable<in T>{
    void Push(T element);
}

:

IPushable<BaseClass> stackB = new Stack<BaseClass>();
IPushable<SubClass> stackS = stackB;
stackS.Push(new SubClass());

, Stack :

interface IPoppable<in T>{
    T Pop();
}

, :

IPoppable<SubClass> stackS = new Stack<SubClass>();
IPoppable<BaseClass> stackB = stackB;
BaseClass baseClass = stackB.Pop();

, - .

+4

, , - , :

public static bool IsSubclassOfRawGeneric(Type generic, Type toCheck)
{
   while (toCheck != null && toCheck != typeof(object))
   {
      var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
      if (generic == cur)
            return true;
      toCheck = toCheck.BaseType;
   }
   return false;
}
+1

, , , , :

Q: , true IList<string> is IList<object>?

-, , , , , .

IList<string> stringList = new List<string>();  
IList<object> objectList = new List<object>();


stringList is IList<string>;
//> true
stringList is IList<object>;
//> false
objectList is IList<string>;
//> false
objectList is IList<object>;
//>true
"someString" is object
//> true

, Generic-Type:

IsGenericType IsGenericConstructedType .

objectList.GetType().GenericTypeArguments[0] is object
//> true
stringList.GetType().GenericTypeArguments[0] is object
//> true

: ; / , .....


Q: ()?

, :

  • IEquality Type :

    bool condition = (someObject != null 
                      && someObject.GetType().Equals(typeof(ISomeInterface<SomeClass>)) );
    
  • :

    var interfaces = someType.GetType().GetInterfaces(); 
    //DotNet4.5: var interfaces = someType.GetType()
    //               .GetTypeInfo().ImplementedInterfaces;
    bool condition = (interfaces != null && interfaces.ToList()
                     .Contains(typeof(ISomeInterface<SomeClass>)) == true);
    

Type TypeInfo

0
source

All Articles