Как проверить, является ли тип IEnumerable <BaseType>? - PullRequest
1 голос
/ 26 сентября 2010

Должно быть легко ...

class Base{}    
class Foo:Base{}

public bool Bar(Type t){
  // return ???
  // NB: shouldn't know anything about Foo, just Base
}

Assert.True(Bar(typeof(IEnumerable<Foo>));
Assert.False(Bar(typeof(IEnumerable<Base>));
Assert.False(Bar(typeof(string));
Assert.False(Bar(typeof(Foo));

Просто чтобы ответить на вопрос, почему второй должен быть ложным (на самом деле - это не имеет значения, потому что аргумент Bar никогда не будет IEnumerable<Base>).

Я пытаюсь написать соглашение об автоматическом отображении FluentNhibernate, которое отображает мои перечисления классов в целые числа.Я уже успешно сделал это, но все пошло не так, когда я хотел отобразить IEnumerable<EnumerationChild> (в моем случае - User.Roles).

public class EnumerationConvention:IUserTypeConvention{
    private static readonly Type OpenType=typeof(EnumerationType<>);
    public void Apply(IPropertyInstance instance){
      //this is borked atm, must implement ienumerable case
      var closedType=OpenType.MakeGenericType(instance.Property.PropertyType);
      instance.CustomType(closedType);
    }
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria){
      criteria.Expect(
        x=>typeof(Enumeration).IsAssignableFrom(x.Property.PropertyType) ||  
           typeof(IEnumerable<Enumeration>)
             .IsAssignableFrom(x.Property.PropertyType));
    }
  }

1 Ответ

3 голосов
/ 26 сентября 2010

Вы можете использовать Type.IsAssignableFrom(Type). Однако ваш вопрос не совсем ясен - вы указываете один тип, но вам нужно два ... какой тип Bar предназначен для проверки t против?

Обратите внимание, что ответ изменится между .NET 3.5 и .NET 4 из-за общей ковариации - в .NET 3.5, например, List<Foo> имеет значение , а не , назначаемое IEnumerable<Base>, но в .NET 4 это так.

РЕДАКТИРОВАТЬ: Вот программа, которая печатает True, True, False, False. Я не уверен, почему вы ожидали, что второй будет ложным:

using System;
using System.Collections;
using System.Collections.Generic;

class Base{}    
class Foo:Base{}

class Test
{
    static bool Bar(Type t)
    {
        return typeof(IEnumerable<Base>).IsAssignableFrom(t);
    }

    static void Main()
    {
        Console.WriteLine(Bar(typeof(IEnumerable<Foo>)));
        Console.WriteLine(Bar(typeof(IEnumerable<Base>)));
        Console.WriteLine(Bar(typeof(string)));
        Console.WriteLine(Bar(typeof(Foo)));
    }
}
...