C#Reflection - 如何判断对象o是否为KeyValuePair类型,然后进行转换?

时间:2010-04-28 13:04:09

标签: c# generics

我正在尝试从LinqPad中编写一个Dump()方法,等同于我自己的问题。我正在从Java迁移到C#,这是一个练习而不是业务需求。除了倾倒字典之外,我几乎所有的东西都在工作。

问题是KeyValuePair是一种Value类型。对于大多数其他值类型,我只需调用ToString方法,但这是不够的,因为KeyValuePair可能包含Enumerables和其他具有不良ToString方法的对象。所以我需要弄清楚它是否是一个KeyValuePair然后再投射它。在Java中,我可以使用通配符泛型,但我不知道C#中的等价物。

你的任务,给定一个对象o,确定它是否是KeyValuePair并在其键和值上调用Print。

Print(object o) {
   ...
}

谢谢!

3 个答案:

答案 0 :(得分:33)

如果您不知道存储在KeyValuePair中的类型,则需要执行一些反射代码。

让我们来看看需要什么:

首先,让我们确保该值不是null

if (value != null)
{

然后,让我们确保该值是通用的:

    Type valueType = value.GetType();
    if (valueType.IsGenericType)
    {

然后,提取通用类型定义,即KeyValuePair<,>

        Type baseType = valueType.GetGenericTypeDefinition();
        if (baseType == typeof(KeyValuePair<,>))
        {

然后提取其中值的类型:

            Type[] argTypes = baseType.GetGenericArguments();

最终代码:

if (value != null)
{
    Type valueType = value.GetType();
    if (valueType.IsGenericType)
    {
        Type baseType = valueType.GetGenericTypeDefinition();
        if (baseType == typeof(KeyValuePair<,>))
        {
            Type[] argTypes = baseType.GetGenericArguments();
            // now process the values
        }
    }
}

如果您发现该对象确实包含KeyValuePair<TKey,TValue>,您可以像这样提取实际的键和值:

object kvpKey = valueType.GetProperty("Key").GetValue(value, null);
object kvpValue = valueType.GetProperty("Value").GetValue(value, null);

答案 1 :(得分:1)

假设您正在使用通用KeyValuePair,那么您可能需要测试特定的实例化,例如使用字符串为键和值创建的实例化:

public void Print(object o) 
{
    if (o == null)
        return;

    if (o is KeyValuePair<string, string>)
    {
        KeyValuePair<string, string> pair = (KeyValuePair<string, string>)o;
        Console.WriteLine("{0} = {1}", pair.Key, pair.Value);
    }
}

如果您想测试任何类型的KeyValuePair,那么您需要使用反射。你呢?

答案 2 :(得分:0)