Skip to content

Instantly share code, notes, and snippets.

@klmr
Created November 30, 2012 09:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save klmr/4174727 to your computer and use it in GitHub Desktop.
Save klmr/4174727 to your computer and use it in GitHub Desktop.
Comprehensive test cases for the IsAssignableToGenericType test
using System;
using System.Collections.Generic;
namespace klmr {
// Version from http://stackoverflow.com/a/75502/1968
public class Test {
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);
}
}
}
namespace jams {
// Version from http://stackoverflow.com/a/1075059/1968
class Test {
public static bool IsAssignableToGenericType(Type givenType, Type genericType)
{
var its = givenType.GetInterfaces();
foreach (var it in its)
{
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);
}
}
}
namespace TestRunner {
class Base<T> { }
interface IBase<T> { }
interface IDerived<T> : IBase<T> { }
class Derived<T> : Base<T>, IBase<T> { }
class Derived2<T> : Derived<T> { }
class DerivedI<T> : IDerived<T> { }
class Tests {
static void Main() {
Console.WriteLine("# Base class");
Console.WriteLine(klmr.Test.IsAssignableToGenericType(typeof(Derived<int>), typeof(Base<>)));
Console.WriteLine(jams.Test.IsAssignableToGenericType(typeof(Derived<int>), typeof(Base<>)));
Console.WriteLine("# Interface");
Console.WriteLine(klmr.Test.IsAssignableToGenericType(typeof(List<int>), typeof(IEnumerable<>)));
Console.WriteLine(jams.Test.IsAssignableToGenericType(typeof(List<int>), typeof(IEnumerable<>)));
Console.WriteLine("# Self");
Console.WriteLine(klmr.Test.IsAssignableToGenericType(typeof(Derived<int>), typeof(Derived<>)));
Console.WriteLine(jams.Test.IsAssignableToGenericType(typeof(Derived<int>), typeof(Derived<>)));
Console.WriteLine("# Transitive base class");
Console.WriteLine(klmr.Test.IsAssignableToGenericType(typeof(Derived2<int>), typeof(Base<>)));
Console.WriteLine(jams.Test.IsAssignableToGenericType(typeof(Derived2<int>), typeof(Base<>)));
Console.WriteLine("# Transitive interface");
Console.WriteLine(klmr.Test.IsAssignableToGenericType(typeof(DerivedI<int>), typeof(IBase<>)));
Console.WriteLine(jams.Test.IsAssignableToGenericType(typeof(DerivedI<int>), typeof(IBase<>)));
Console.WriteLine("# Transitive base class to interface");
Console.WriteLine(klmr.Test.IsAssignableToGenericType(typeof(Derived2<int>), typeof(IBase<>)));
Console.WriteLine(jams.Test.IsAssignableToGenericType(typeof(Derived2<int>), typeof(IBase<>)));
Console.WriteLine("# Nullable type");
Console.WriteLine(klmr.Test.IsAssignableToGenericType(typeof(int?), typeof(Nullable<>)));
Console.WriteLine(jams.Test.IsAssignableToGenericType(typeof(int?), typeof(Nullable<>)));
Console.WriteLine("# Negative control: non-generic base");
Console.WriteLine(klmr.Test.IsAssignableToGenericType(typeof(Derived<int>), typeof(Object)));
Console.WriteLine(jams.Test.IsAssignableToGenericType(typeof(Derived<int>), typeof(Object)));
Console.WriteLine("# Negative control: non-base class");
Console.WriteLine(klmr.Test.IsAssignableToGenericType(typeof(Derived<int>), typeof(List<>)));
Console.WriteLine(jams.Test.IsAssignableToGenericType(typeof(Derived<int>), typeof(List<>)));
Console.WriteLine("# Negative control: non-base interface");
Console.WriteLine(klmr.Test.IsAssignableToGenericType(typeof(Derived<int>), typeof(IEnumerable<>)));
Console.WriteLine(jams.Test.IsAssignableToGenericType(typeof(Derived<int>), typeof(IEnumerable<>)));
Console.WriteLine("# Negative control: concrete class");
Console.WriteLine(klmr.Test.IsAssignableToGenericType(typeof(Derived<int>), typeof(Base<int>)));
Console.WriteLine(jams.Test.IsAssignableToGenericType(typeof(Derived<int>), typeof(Base<int>)));
Console.WriteLine("# Negative control: concrete interface");
Console.WriteLine(klmr.Test.IsAssignableToGenericType(typeof(List<int>), typeof(IEnumerable<int>)));
Console.WriteLine(jams.Test.IsAssignableToGenericType(typeof(List<int>), typeof(IEnumerable<int>)));
Console.WriteLine("# Negative control: non-nullable type");
Console.WriteLine(klmr.Test.IsAssignableToGenericType(typeof(int), typeof(Nullable<>)));
Console.WriteLine(jams.Test.IsAssignableToGenericType(typeof(int), typeof(Nullable<>)));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment