Type.GetInterface and nested types

2019-07-16 08:11发布

问题:

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.

回答1:

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.



回答2:

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?



回答3:

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.