派生类型和泛型

时间:2016-06-01 13:56:34

标签: c# .net generics inheritance

我有一种使用泛型的类型。我们称之为FlowerDescriptor<T>一些鲜花是用数字描述的,有些则用字符串等来描述。

所以FlowerDescriptor<int>; FlowerDescriptor<string>;

我想要一个机制(可能是扩展方法)来做两件事

  • 查看某些内容 FlowerDescriptor
  • 查看描述符是什么。

  • FlowerDescriptor<string>.GetType().IsFlowerDescriptor == true string.GetType().IsFlowerDescriptor == false

同样地,我可能来自FlowerDescriptor<int>,即class NumberedFlower: FlowerDescriptor<int>

new NumberedFlower.GetType()。IsFlowerDesriptor == true;

  • 如上所述但返回类型 FlowerDescriptor<string>.GetType().GetFlowerDescriptor() == typeof(string) FlowerDescriptor<int>.GetType().GetFlowerDescriptor() == typeof(int) new NumberedFlower.GetType().GetFlowerDescriptor() == typeof(int)

我玩过IsAssignableFrom的变体,感觉应该与typeof(FlowerDescriptor<>).IsAssignableFrom(typeof(FlowerDescriptor<string>))

一起使用

但它不起作用。如果它添加泛型类型,但它确实如此。

我目前正在探索GetInterfaces以了解可用的界面。真的很了解我做错了什么......

4 个答案:

答案 0 :(得分:4)

除非你想在混音中添加界面,否则唯一的选择是

  1. 检测到该类型实际上是FlowerDescriptor<T>
  2. 或从FlowerDescriptor<T>
  3. 中检测到继承类型

    不幸的是,当涉及到开放泛型时,我认为你不能使用IsAssignableFrom,这意味着我们不得不将继承链带到基类。

    以下是一个能做正确事情的示例代码:

    public static bool IsFlowerDescriptor(this Type type)
    {
        if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(FlowerDescriptor<>))
            return true;
        if (type.BaseType != null)
            return type.BaseType.IsFlowerDescriptor();
    
        return false;
    }
    

    以下是您可以试验的.NET Fiddle

答案 1 :(得分:2)

我不希望字符串或int类知道它是否是描述符,从FlowerDescriptor获取该信息更有意义。

如果您想使用反射,可以从FlowerDescriptor实例中获取泛型类型定义

FlowerDescriptor<int> f = new FlowerDescriptor<int>();
Type t = f.GetType();
Type[] typeArguments = t.GetGenericArguments();
//check if type you care about is in typeArguments

答案 2 :(得分:0)

以下是获得这两个值的方法:

bool isFlowerDescriptor = x is FlowerDescriptor<object>;

Type descriptorType = x.GetType().GetGenericArguments()[0];

如果您愿意,可以将它们包装在扩展方法中。并添加空检查等。

答案 3 :(得分:0)

您可能会考虑使用非泛型基类。然后你的结构看起来像:

public abstract class FlowerDescriptor { }

public class FlowerDescriptor<T> : FlowerDescriptor { }

public class NumberedFlower : FlowerDescriptor<int> { }

你的2个扩展名是:

public static class Extensions
{
    public static bool IsFlowerDescriptor(this object o)
    {
        return o is FlowerDescriptor;
    }

    public static Type GetFlowerDescriptor<T>(this FlowerDescriptor<T> o)
    {
        return typeof (T);
    }
}

你会像以下一样使用它:

public static void Main()
{
    Console.WriteLine(new NumberedFlower().IsFlowerDescriptor());  //true
    Console.WriteLine(new NumberedFlower().GetFlowerDescriptor()); //System.Int32
}

泛型在反映和比较类型时会产生负面影响,因为FlowerDescriptor<int>FlowerDescriptor<string>的类型不同。这是我没有找到一个好节奏的东西。