繁体   English   中英

如何将任何类型的泛型转换为另一种类型

[英]How to Cast a generic type of any type to another type

我正在尝试创建一种递归方法,该方法通过检查哈希值是否为另一本字典来将字典的深层副本复制为任意长度,然后在对其进行哈希处理之前再次复制它。

我已经尝试过了,编译器拒绝了Blockquote中的行,谁能找到错误?

private Dictionary<TKey, TValue> NestedCopy<TKey, TValue>(Dictionary<TKey, 
                                                         TValue> nestedDict)
{

    var retDict = new Dictionary<TKey, TValue>();
    foreach (var dict in nestedDict)
    {
         if (dict.Value is Dictionary<Object, Object>)
         {
             retDict[dict.Key] = NestedCopy(dict.Value asDictionary<object, object>);
         }
     }
     return retDict;
}

retDict [dict.Key] = NestedCopy(dict.Value asDictionary);

这是错误行,

它说它不能隐式地从Dictionary转换为TValue

Dictionary<string, Dictionary<string, int>> dict; 
var newDict = NestedCopy(newDict);
//I expect newDict to be a copy of dict

编译器无法静态推断递归调用。 因此,您将需要反射或至少让编译器使用dynamic关键字为您完成反射:

private Dictionary<TKey, TValue> NestedCopy<TKey, TValue>(
    Dictionary<TKey, TValue> nestedDict)
{
    var retDict = new Dictionary<TKey, TValue>();
    foreach (var dict in nestedDict)
    {
        if (typeof(TValue).IsGenericType && typeof(TValue).GetGenericTypeDefinition() == typeof(Dictionary<,>))
        {
            retDict[dict.Key] = (TValue)NestedCopy((dynamic)dict.Value);
        }
        else
        {
            retDict[dict.Key] = dict.Value;
        }
    }
    return retDict;
}

具有手工反射功能的更明确的代码如下所示:

private static Dictionary<TKey, TValue> NestedCopy<TKey, TValue>(
    Dictionary<TKey, TValue> nestedDict)
{
    var reflectionMethod = typeof(Program).GetMethod("NestedCopy", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
    var retDict = new Dictionary<TKey, TValue>();
    foreach (var dict in nestedDict)
    {
        if (typeof(TValue).IsGenericType && typeof(TValue).GetGenericTypeDefinition() == typeof(Dictionary<,>))
        {
            var methodToCall = reflectionMethod.MakeGenericMethod(typeof(TValue).GetGenericArguments());
            retDict[dict.Key] = (TValue)methodToCall.Invoke(null, new object[] { dict.Value });
        }
        else
        {
            retDict[dict.Key] = dict.Value;
        }
    }
    return retDict;
}

注意,此方法假定该方法属于Program类,并且由于未使用任何上下文,因此将其设为静态。

由于if-else的决定不取决于dict.Value而是仅取决于在整个方法中保持不变的TValue ,因此您还可以将条件移出循环:

private static Dictionary<TKey, TValue> NestedCopy<TKey, TValue>(
    Dictionary<TKey, TValue> nestedDict)
{
    var retDict = new Dictionary<TKey, TValue>();
    Func<TValue, TValue> clone;
    if (typeof(TValue).IsGenericType && typeof(TValue).GetGenericTypeDefinition() == typeof(Dictionary<,>))
    {
        clone = v => NestedCopy((dynamic)v);
    }
    else
    {
        clone = v => v;
    }
    foreach (var dict in nestedDict)
    {
        retDict[dict.Key] = clone(dict.Value);
    }
    return retDict;
}

我认为您不需要递归它,它取决于您如何实现TValue.Clone方法。

private Dictionary<TKey, TValue> CloneDictionary<TKey, TValue>(Dictionary<TKey, TValue> sourceDic)
            where TValue : ICloneable
        {
            var ret = new Dictionary<TKey, TValue>(sourceDic.Count, sourceDic.Comparer);
            foreach (KeyValuePair<TKey, TValue> entry in sourceDic)
            {
                ret.Add(entry.Key, (TValue)entry.Value.Clone());
            }
            return ret;
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM