views:

348

answers:

3

Hi,

I just discovered a very strange behavior with Type.GetInterface and nested Types.

The following sample code will show the problem, I am using the Type.FullName of an interface to check whether a given type derives from that interface:

public interface IStandardInterface {}
public class StandardClass : IStandardInterface {}

class Program
{
 public interface INestedInterface {}
 public class NestedClass : INestedInterface { }

 static void Main()
 {
  var stdIfName = typeof (IStandardInterface).FullName;
  var nestedIfName = typeof (INestedInterface).FullName;

  var std = typeof(StandardClass).GetInterface(stdIfName);
  var nested = typeof(NestedClass).GetInterface(nestedIfName);
 }
}

If I execute the code above it works for StandardClass but not for NestedClass.

  • std has a value of typeof(IStandardInterface)
  • nested has a value of null


Is this behavior expected or a bug? If it is expected could you explain why?

I use .net Framework version 3.5 SP1.

+2  A: 

It looks like a bug handling the "+" marker for nested names... the following (cheating with LINQ) works:

var nested = typeof(NestedClass).GetInterfaces()
            .SingleOrDefault(i => i.FullName == nestedIfName);

Of course, in most cases you would just use is or as (or maybe IsAssignableFrom) to test against an interface... what is the use-case here?

Marc Gravell
I converted it to thisType.GetInterfaces().Contains(interfaceType), i need it to check if a factory returns objects which are of a specific interface (so i don't have a instance to use is/as).
Fionn
+1  A: 

I was not reading the question correctly. This should do what you need.

Boolean isSubClass = typeof(NestedClass).GetInterfaces().Contains(typeof(INestedInterface));

Original Answer:

I am not sure if that is a bug or not but this is the code I used to test if a type derives from another type.

typeof(NestedClass).IsInstanceOfType(typeof(IStandardInterface))

I have had problems when you convert it to names in the past. I think in general you should stay with the actual Type objects if you can.

Shaun Bowe
To me seems that this method checks if a given instance is of the current type. And if you use a Type instance as argument it would only return true for things like typeof(Type).IsInstanceOfType(typeof(IStandardInterface))
Fionn
+3  A: 

Expanding on Marc's answer.

Although it's not documented, the GetInterface API will break up the name you pass in based on the position of the last "." in the name. Everything to the right of the "." will be assumed to be the short name of the interface in question.

This poses a problem for nested types as they will have a name which is "ContainingTypeName+NestedTypeName". So when you pass in the full name to GetInterface it actually ends up looking for an interface named "Program+INestedInterface" which it won't find.

JaredPar