How to determine IDeclaredType representing a generic List type?

Hello,

I'm newbie in R# API and I would ask you to help make my code better. Let's assume we have declaredType variable implementing IDeclaredType interface. How to check is declaredType actually representing List<Foo>, IList<Foo> or not?

My solution is:

ITypeElement element = declaredType.GetTypeElement();


string fullName = element.GetClrName().FullName;


bool isGenericList = fullName == "System.Collections.Generic.List`1"
                  || fullName == "System.Collections.Generic.IList`1";

It works but looks bad! I'm sure a correct way to compare generic types exists in R# API instead of this string comparison. Any advice is appreciated!


ReSharper SDK 9.2 is used.
3 comments
Comment actions Permalink

Any ideas, guys?

0
Comment actions Permalink

You want to do something like this. The PredefinedType class has a number of properties to get the IDeclaredType of IEnumerable<T>, List<T>, IList<T> and so on. Once you've got this, you can use TypeFactory to create a type and EmptySubstitution.Extend to create a closed generic type (e.g. IList<string>) if you wish. If you're working with a closed generic, you can use a type conversion rule (e.g. new CSharpTypeConversionRule(declaredElement.Module)) to see if another type can be converted to it - in other words, if another type implements IList<string>. If you're looking to see if a given type is an open generic, such as IList<T> or List<T>, you can compare the two declared elements with a simple equals.

0
Comment actions Permalink

Matt Ellis, thanks!

This is the solution how to detect is IDeclaredType derived from closed List<T> or not, and it is based on code you gave:

 
IMethod declaredElement = method.DeclaredElement;
 
IDeclaredType declaredType = declaredElement?.ReturnType as IDeclaredType;
 
ISubstitution sub = declaredType.GetSubstitution();
 
IType  parameterType = sub.Apply(sub.Domain[0]);
 
IType realType = declaredElement.Type();
 
PredefinedType predefinedType = declaredElement.Module.GetPredefinedType();
 
ITypeElement generic = predefinedType.GenericList.GetTypeElement();
 
IType sampleType = EmptySubstitution.INSTANCE
     .Extend(generic.TypeParameters, new IType[] { parameterType })
     .Apply(predefinedType.GenericList);
 
bool good = realType.IsImplicitlyConvertibleTo(sampleType, new CSharpTypeConversionRule(declaredElement.Module));
0

Please sign in to leave a comment.