Как обращаться с общим словарем, типы которого неизвестны и не имеют значения? - PullRequest
5 голосов
/ 24 февраля 2010

Если 'value' - это входящий универсальный словарь, типы которого неизвестны / не имеют значения, как мне взять его записи и поместить их в целевой словарь типа IDictionary<object, object>?

if(type == typeof(IDictionary<,>))
{
    // this doesn't compile 
    // value is passed into the method as object and must be cast       
    IDictionary<,> sourceDictionary = (IDictionary<,>)value;

    IDictionary<object,object> targetDictionary = new Dictionary<object,object>();

    // this doesn't compile
    foreach (KeyValuePair<,> sourcePair in sourceDictionary)
    {
         targetDictionary.Insert(sourcePair.Key, sourcePair.Value);
    }

    return targetDictionary; 
}

EDIT:

Спасибо за ответы до сих пор.

Проблема здесь в том, что аргумент Copy известен только как тип 'object'. Например:

public void CopyCaller(object obj) 
{ 
    if(obj.GetType() == typeof(IDictionary<,>) 
         Copy(dictObj); // this doesn't compile 
} 

Ответы [ 5 ]

5 голосов
/ 24 февраля 2010

Сделайте свой метод также общим, и тогда вы сможете делать то, что делаете. Вам не нужно будет менять шаблон использования, поскольку компилятор сможет выводить универсальные типы из типов ввода.

public IDictionary<object, object> Copy(IDictionary<TKey, TValue> source)
{

    IDictionary<object,object> targetDictionary = new Dictionary<object,object>();

    foreach (KeyValuePair<TKey, TValue> sourcePair in sourceDictionary)
    {
         targetDictionary.Insert(sourcePair.Key, sourcePair.Value);
    }

    return targetDictionary; 
}

Если вам действительно не нужно преобразовывать его из IDictionary<TKey, TValue> в IDictionary<object, object>, тогда вы можете использовать конструктор копирования Dictionary<TKey, TValue>, который принимает другой словарь в качестве входных данных и копирует все значения - так же, как вы делаете Теперь.

1 голос
/ 24 февраля 2010

Вот метод (не оставляйте его как статический, если вам это не нужно, я написал его в быстром консольном приложении), который в основном преобразует Словарь любого типа в словарь объектов / объектов.

    private static Dictionary<object,object> DeTypeDictionary<T,U>(Dictionary<T,U> inputDictionary)
    {
        Dictionary<object, object> returnDictionary = new Dictionary<object, object>();
        foreach(T key in inputDictionary.Keys)
        {
            if( (key is object) && (inputDictionary[key] is object))
            {
                returnDictionary.Add(key, inputDictionary[key]);
            }
            else
            {
                //sorry these aren't objects. they may be dynamics.
                continue;
            }

        }
        return returnDictionary;
    }

... и вот как вы его используете ...

        Dictionary<string, DateTime> d = new Dictionary<string, DateTime>();
        d.Add("rsgfdg", DateTime.Now);
        d.Add("gfdsgd", DateTime.Now);

        Dictionary<object, object> newDictionary = DeTypeDictionary<string, DateTime>(d);
0 голосов
/ 25 апреля 2019

Вы можете использовать тот факт, что универсальные словари реализуют интерфейс IDictionary.

private static Dictionary<object, object> CreateCopy(IDictionary source)
{
    var copy = new Dictionary<object, object>(source.Count);
    foreach (DictionaryEntry entry in source)
    {
        copy.Add(entry.Key, entry.Value);
    }
    return copy;
}

Пример использования:

var source = new Dictionary<int, string>() { { 1, "Foo" }, { 2, "Bar" }, };
var copy = CreateCopy(source);
Console.WriteLine(String.Join(", ", copy.Values));

Выход:

Фу, Бар

0 голосов
/ 25 апреля 2019

Итак, у вас есть объект, который может быть словарем, и вы хотите:

  • Проверить это словарь
  • Действуйте соответствующим образом, если это

Давайте начнем с универсальной функции, которая делает то, что вы хотите, если вы знали аргументы типа:

class Bar
{
    public static void Foo<TKey, TValue>(Dictionary<TKey, TValue> input) { ... }
}

Теперь нам просто нужно подумать

bool TryHandleDictionary(object o)
{
    var t = o.GetType();
    if (!t.IsGenericType || t.GetGenericTypeDefinition() != typeof(Dictionary<,>)) return false;

    var m = typeof(Bar).GetMethod("Foo", BindingFlags.Public | BindingFlags.Static);
    var m1 = m.MakeGenericMethod(t.GetGenericArguments());
    m1.Invoke(null, new[] { o });
    return true;
}
0 голосов
/ 24 февраля 2010

Это может быть исправлением для вас, но вам понадобится .net 3.5 или выше, чтобы использовать ключевое слово var.

// this should compile
foreach (var sourcePair in sourceDictionary)
{
     targetDictionary.Insert(sourcePair.Key, sourcePair.Value);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...