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

Log*_*gan 11 c# generics

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

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

在给定对象o的情况下,您的任务确定它是否为KeyValuePair并在其键和值上调用Print.

Print(object o) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

谢谢!

ang*_*son 35

如果你不知道存储的类型,KeyValuePair你需要运用一些反射代码.

让我们来看看需要什么:

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

if (value != null)
{
Run Code Online (Sandbox Code Playgroud)

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

    Type valueType = value.GetType();
    if (valueType.IsGenericType)
    {
Run Code Online (Sandbox Code Playgroud)

然后,提取泛型类型定义,即KeyValuePair<,>:

        Type baseType = valueType.GetGenericTypeDefinition();
        if (baseType == typeof(KeyValuePair<,>))
        {
Run Code Online (Sandbox Code Playgroud)

然后提取其中的值类型:

            Type[] argTypes = baseType.GetGenericArguments();
Run Code Online (Sandbox Code Playgroud)

最终代码:

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

object kvpKey = valueType.GetProperty("Key").GetValue(value, null);
object kvpValue = valueType.GetProperty("Value").GetValue(value, null);
Run Code Online (Sandbox Code Playgroud)

  • 这里使用反射会影响性能吗? (2认同)