Using IsAssignableFrom with 'open' generic types

isassignablefrom java
isassignablefrom c
isassignablefrom vs issubclassof
isassignablefrom generic
isassignablefrom generic java
isassignablefrom kotlin
isassignablefrom vs instanceof
isassignablefrom interface

Using reflection, I'm attempting to find the set of types which inherit from a given base class. It didn't take long to figure out for simple types, but I'm stumped when it comes to generics.

For this piece of code, the first IsAssignableFrom returns true, but the second returns false. And yet, the final assignment compiles just fine.

class class1 { }
class class2 : class1 { }
class generic1<T> { }
class generic2<T> : generic1<T> { }

class Program
{
    static void Main(string[] args)
    {
        Type c1 = typeof(class1);
        Type c2 = typeof(class2);
        Console.WriteLine("c1.IsAssignableFrom(c2): {0}", c1.IsAssignableFrom(c2));

        Type g1 = typeof(generic1<>);
        Type g2 = typeof(generic2<>);
        Console.WriteLine("g1.IsAssignableFrom(g2): {0}", g1.IsAssignableFrom(g2));

        generic1<class1> cc = new generic2<class1>();
    }
}

So how do I determine at run time whether one generic type definition is derived from another?


From the answer to another question:

public static bool IsAssignableToGenericType(Type givenType, Type genericType)
{
    var interfaceTypes = givenType.GetInterfaces();

    foreach (var it in interfaceTypes)
    {
        if (it.IsGenericType && it.GetGenericTypeDefinition() == genericType)
            return true;
    }

    if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
        return true;

    Type baseType = givenType.BaseType;
    if (baseType == null) return false;

    return IsAssignableToGenericType(baseType, genericType);
}

(If you like the answer please upvote the linked answer since the code isn’t mine.)

Type.IsAssignableFrom(Type) Method (System), Class.isAssignableFrom() determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the� The java.lang.Class.isAssignableFrom() determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter. Declaration. Following is the declaration for java.lang.Class.isAssignableFrom() method


The exact code you posted does not return surprising results.

This says "false":

Type g1 = typeof(generic1<>);
Type g2 = typeof(generic2<>);
Console.WriteLine("g1.IsAssignableFrom(g2): {0}", g1.IsAssignableFrom(g2));

This says "true":

Type g1 = typeof(generic1<class1>);
Type g2 = typeof(generic2<class1>);
Console.WriteLine("g1.IsAssignableFrom(g2): {0}", g1.IsAssignableFrom(g2));

The difference is that open generic types cannot have instances, so one is not "assignable" to the other.

From the docs:

Returns true if c and the current Type represent the same type, or if the current Type is in the inheritance hierarchy of c, or if the current Type is an interface that c implements, or if c is a generic type parameter and the current Type represents one of the constraints of c. false if none of these conditions are true, or if c is null.

In this case, clearly none of these conditions are true. And there's an extra note:

A generic type definition is not assignable from a closed constructed type. That is, you cannot assign the closed constructed type MyGenericList<int> (MyGenericList(Of Integer) in Visual Basic) to a variable of type MyGenericList<T>.

Java.lang.Class.isAssignableFrom() Method, It returns false otherwise. Syntax: public boolean isAssignableFrom(Class<T> class). Parameter: This method accepts class as parameter which� The IsAssignableFrom method can be used to determine whether an instance of c can be assigned to an instance of the current type, The method is most useful when you are handling objects whose types are not known at design time and allows for conditional assignment, as the following example shows. C#.


In the following case use the method Konrad Rudolph provided could be wrong, like: IsAssignableToGenericType(typeof(A), typeof(A<>));// return false

I think here's a better answer

public static bool IsAssignableFrom(Type extendType, Type baseType)
{
    while (!baseType.IsAssignableFrom(extendType))
    {
        if (extendType.Equals(typeof(object)))
        {
            return false;
        }
        if (extendType.IsGenericType && !extendType.IsGenericTypeDefinition)
        {
            extendType = extendType.GetGenericTypeDefinition();
        }
        else
        {
            extendType = extendType.BaseType;
        }
    }
    return true;
}

the test case, see Using IsAssignableFrom with C# generics for detail

using System;

/**
 * Sam Sha - yCoder.com
 *
 * */
namespace Test2
{
    class MainClass
    {
        public static void Main (string[] args)
        {
            string a = "ycoder";
            Console.WriteLine(a is object);
            A aa = new A();
            //Console.WriteLine(aa is A<>);//con't write code like this
            typeof(A<>).IsAssignableFrom(aa.GetType());//return false

            Trace(typeof(object).IsAssignableFrom(typeof(string)));//true
            Trace(typeof(A<>).IsAssignableFrom(typeof(A)));//false

            AAA aaa = new AAA();
            Trace("Use IsTypeOf:");
            Trace(IsTypeOf(aaa, typeof(A<>)));
            Trace(IsTypeOf(aaa, typeof(AA)));
            Trace(IsTypeOf(aaa, typeof(AAA<>)));

            Trace("Use IsAssignableFrom from stackoverflow - not right:");
            Trace(IsAssignableFrom(typeof(A), typeof(A<>))); // error
            Trace(IsAssignableFrom(typeof(AA), typeof(A<>)));
            Trace(IsAssignableFrom(typeof(AAA), typeof(A<>)));

            Trace("Use IsAssignableToGenericType:");
            Trace(IsAssignableToGenericType(typeof(A), typeof(A<>)));
            Trace(IsAssignableToGenericType(typeof(AA), typeof(A<>)));
            Trace(IsAssignableToGenericType(typeof(AAA), typeof(A<>)));
        }

        static void Trace(object log){
                Console.WriteLine(log);
        }

        public static bool IsTypeOf(Object o, Type baseType)
        {
            if (o == null || baseType == null)
            {
                return false;
            }
            bool result = baseType.IsInstanceOfType(o);
            if (result)
            {
                return result;
            }
            return IsAssignableFrom(o.GetType(), baseType);
        }

        public static bool IsAssignableFrom(Type extendType, Type baseType)
        {
            while (!baseType.IsAssignableFrom(extendType))
            {
                if (extendType.Equals(typeof(object)))
                {
                    return false;
                }
                if (extendType.IsGenericType && !extendType.IsGenericTypeDefinition)
                {
                    extendType = extendType.GetGenericTypeDefinition();
                }
                else
                {
                    extendType = extendType.BaseType;
                }
            }
            return true;
        }

        //from stackoverflow - not good enough
        public static bool IsAssignableToGenericType(Type givenType, Type genericType) {
            var interfaceTypes = givenType.GetInterfaces();

            foreach (var it in interfaceTypes)
                if (it.IsGenericType)
                    if (it.GetGenericTypeDefinition() == genericType) return true;

            Type baseType = givenType.BaseType;
            if (baseType == null) return false;

            return baseType.IsGenericType &&
                baseType.GetGenericTypeDefinition() == genericType ||
                IsAssignableToGenericType(baseType, genericType);
        }
    }

    class A{}
    class AA : A{}
    class AAA : AA{}
}

Class isAssignableFrom() method in Java with Examples , Type.IsAssignableFrom(Type) Method is used determine whether an instance of a Below programs illustrate the use of Type. using GetProperties() Method. Using IsAssignableFrom with 'open' generic types. Ask Question Asked 9 years, 4 months ago. Active 7 months ago. Viewed 27k times 69. 8. Using reflection, I'm


You need to compare the contained type. See: How to get the type of T from a member of a generic class or method?

In other words, I think you need to check whether the type being contained by the generic class is assignable rather than the generic class itself.

C#, The MSDN documentation for the IsAssignableFrom method states: In general, doing reflection is an expensive business and you should� Type.IsAssignableFrom(Type) Method is used determine whether an instance of a specified type can be assigned to a variable of the current type. Syntax: public virtual bool IsAssignableFrom (Type c); Here, it takes the type to compare with the current type. Return Value: This method returns true if any of the following conditions is true:


I have a different Approach that resolves this issue, Here are my classes

public class Signal<T>{
   protected string Id {get; set;} //This must be here, I use a property because MemberInfo is returned in an array via GetMember() reflection function
   //Some Data and Logic And stuff that involves T
}

public class OnClick : Signal<string>{}

Now if I have an instance of type OnClick but I dont know that, and I want to find out if I have an instance of anything which inherits from Signal<> of any type? I do this

Type type = GetTypeWhomISuspectMightBeAGenericSignal();

PropertyInfo secretProperty = type.GetProperty("Id", BindingFlags.NonPublic | BindingFlags.Instance);

Type SpecificGenericType = secretProperty.DeclaringType; //This is the trick

bool IsMyTypeInheriting = SpecificGenericType.IsGenericType && SpecificGenericType.GetGenericTypeDefinition() == typeof(Signal<>); //This way we are getting the genericTypeDefinition and comparing it to any other genericTypeDefinition of the same argument length.

So this works for me, its not recursive, and it uses a trick via a designated property. It has limitations that its hard to write a function that checks assignability for all generics ever. But for a specific type it works

Obviously you need to check if() conditions better and stuff, but these are the Raw lines required to evaluate assignability of a type to its base generic, this way.

Hope this helps

Type.IsSubclssOf and Type.IsAssignableFrom, How to use. isAssignableFrom. method. in. java.lang.Class. Best Java code snippets using java� In order to use isInstance, we need to know what one of the classes is at compile time. Only isAssignableFrom can be used with primitives. We should note that if we're using primitives, the method will only return true if the Class object and Class parameter are exactly the same Class.


java.lang.Class.isAssignableFrom java code examples, IsAssignableFrom(Type) is quite common to mistakenly use subject and object; the type you are interested in becoming a parameter rather t IsAssignableFrom works with types, and is works with instances. They will give you the same results in your case, so you should use the simplest version IMHO. As for IsInstanceOfType:That is implemented in terms of IsAssignableFrom, so there will be no difference. You can prove that by using Reflector to look at the definition of IsInstanceOfType():


API Proposal: Type.IsAssignableTo(Type) � Issue #30714 � dotnet , You can make such determinations using reflection. IsAssignableFrom. In previous articles we've seen how you can use reflection to find classes� This thread provided me some insight into how instanceof differed from isAssignableFrom, so I thought I'd share something of my own.. I have found that using isAssignableFrom to be the only (probably not the only, but possibly the easiest) way to ask one's self if a reference of one class can take instances of another, when one has instances of neither class to do the comparison.


Checking if Types are Compatible, In this quick tutorial, we're going to take a look at the difference between Class. isInstance and Class.isAssignableFrom. We'll learn how to use� It is preferable to use Assert.IsAssignableFrom<>() to check if the type of the returned IActionResult is what you expect it to be. Summary Writing unit tests for ASP.NET Core MVC Controller is not too different from unit testing other classes, with the main exceptions of setting up the controller class and using Assert.IsAssignableFrom<>() to