EmpireWorld Ответов: 3

Как мне привести объект в словарь?


Как мне привести объект в словарь?

Ключ и значение словаря могут быть любого типа.

Что я уже пробовал:

public class Example {

    void CallMethod () {
        SomeMethod (new Dictionary<string, bool> ());
        SomeMethod (new Dictionary<int, long> ());
        SomeMethod<Dictionary<string, bool>> (new Dictionary<string, bool> ());
    }
    
    void SomeMethod (object value) {
        var dic = value as Dictionary<,>;
        // What is type of Dictionary key or value?
    }

    void SomeMethd<T> (T value) {
        // T can be Dictionary, int, bool, List, ...
        if (value is Dictionary) {
            // T is dictionary, but we don't know type of key and value
            // How do i cast it to dictionary?
            var dic = value as Dictionary<,>;
            foreach (var item in dic) {
                
            }
        }
    }

    T SomeMethod<T> () {
        // I want to load the dictionary here
        if (typeof(T) is IDictionary) {
            // Now, what is type of the key and value?
            IDictionary dic = new Dictionary<,> ();
            int count = 1;
            for (int i = 0; i < count; i++) {
                dic.Add (SomeMethod<Type of Key> (), SomeMethod<Type of value> ());
            }
            // Throws an exception
            return dic;
        }
        return default(T);
    }
    
}

Mehdi Gholam

Что вы собираетесь делать в SomeMethod ()?

EmpireWorld

Я хочу написать объект с помощью BinaryWriter.

3 Ответов

Рейтинг:
2

OriginalGriff

Если вы не знаете тип словаря - а это означает ключ и значение, - единственный способ сделать это-привести его к словарю "объект, объект", что является очень плохой идеей, поскольку он избавляется от сильной типизации, которая делает C# таким надежным. На данный момент Вы полагаетесь на runtime-casts для использования созданного вами словаря, и это плохая идея.

Рассматривали ли вы вместо этого возможность использования дженериков, чтобы вам не нужно было приводить свой словарь, типы выводятся при вызове метода?

void SomeMethod<K, V>(Dictionary<K, V> dict)
    {
    ///...
    }
Это сделает ваш код более надежным и гораздо более легким для чтения.


EmpireWorld

Мне нужен метод, который принимает только один универсальный тип и один аргумент, который принимает примитивные типы, универсальные типы, такие как коллекции, список, Словарь и пользовательские классы. Так как же мне это сделать, пока вы говорите сделать перегрузку для словаря?

OriginalGriff

Поскольку доступные свойства и методы различны, я бы произвел перегрузки, которые принимают дженерики:
пустота метода someMethod&ЛТ;К в&ГТ;(словарь&ЛТ;К в&ГТ; дикт)
{
///...
}
void SomeMethod< t> (List< t> list)
{
}
пустота метода someMethod в<Т>(интерфейс IEnumerable&ЛТ;п&ГТ; перечисли)
{
}
Вы можете добавить к ним другие параметры по мере необходимости.

EmpireWorld

Пожалуйста, проверьте T SomeMethod< t> (); в вопросе, мне нужен рекурсивный метод.

OriginalGriff

Не надо: создайте метод, который принимает общий словарь< K, V> и K-это тип ключа, а V-тип значения. Вы можете использовать их внутри метода для создания новых экземпляров или того, что вам нужно.

Чего вы пытаетесь достичь? Вы, кажется, слишком все усложняете.

EmpireWorld

Я пытаюсь сделать решение для сохранения и загрузки.

Я хочу иметь возможность сохранять все, что угодно, например словари, пользовательские классы ...

То, что у меня есть, - это единственный метод сохранения и загрузки.

Сохранить<t> (значение T);

и

Нагрузка< t> ();

Мне нужно рекурсивное сохранение и загрузка функционально для обоих.

Как мне этого добиться?

OriginalGriff

А-точно.
Не сворачивайте свой собственный-есть уже существующие решения, которые делают это уже сейчас, и в удобном портативном виде. Вы рассматривали возможность использования JSON?
Это может помочь:
https://www.codeproject.com/Articles/272335/JSON-Serialization-and-Deserialization-in-ASP-NET
Google найдет вам множество примеров, которые уже сделают эту работу за вас!

EmpireWorld

Я хочу сделать это с помощью двоичного кода. Как мне этого добиться?

Также словарь в<строка, типа bool и GT; может быть словарь&ЛТ;словарь на<строка, инт&ГТ;, типа bool и GT;, что мне делать, когда словари вложены?

Как получить тип ключа и значение словаря из T?

OriginalGriff

Вот почему "заварить свой собственный" - это такая боль в но - вы должны справиться со всем, ничего не зная о том, что вы сериализуете, что делает его действительно очень сложным.
Почему именно двоичный код? Если это "человекочитаемая" вещь, то потоки JSON или XML и зашифрованный контейнер сделают это лучше, а если это космическая вещь, то JSON / XML и ZIP-контейнер могут работать хорошо.
Если это потому, что вам очень, очень нравится тестировать крайние случаи и тратить несколько недель на исправление ошибок, то это может помочь вам начать работу:
https://www.codeproject.com/Articles/15646/A-Deep-XmlSerializer-Supporting-Complex-Classes-En
Это стоит прочитать в качестве фона для того, что вы пытаетесь сделать сами, даже если вы не используете какой-либо код.

EmpireWorld

Как Json.NET сериализует объекты?

Нет никакой разницы, что вы передаете, он просто сериализует это.

Так как же можно сделать то же самое? Как Json.Нетто это делает?

OriginalGriff

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

EmpireWorld

Спасибо, но мне нужно сделать это самому, не могли бы вы объяснить, как JSON.net добился этого?

OriginalGriff

Не в тех деталях, которые вам понадобятся - я не писал JSON, поэтому не знаю, что это внутреннее.
Я бы сказал, что он использует отражение точно так же, как и последняя страница, на которую я ссылался.

Рейтинг:
1

Mehdi Gholam

В зависимости от того, насколько информация о типе важна для вас в рамках SomeMethod() метод, который вы можете сделать:

// minimal type info needed
void SomeMethod (System.Collections.IDictionary dictionary)
{
   foreach(var k in dictionary.Keys)
   {
      // k and dictionary[k] as value
   }
}

Или если типы необходимы:
// overloaded for each case
void SomeMethod (System.Collections.Generic.Dictionary<int,long> dictionary)
{
   foreach(var kv in dictionary)
   {
      //access to kv.Key and kv.Value as int and long
   }
}

void SomeMethod (System.Collections.Generic.Dictionary<string,bool> dictionary)
{
   foreach(var kv in dictionary)
   {
      //access to kv.Key and kv.Value as string and bool
   }
}


EmpireWorld

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

Mehdi Gholam

Извини, исправлено.

EmpireWorld

Что такое тип к? это объект?

Как я проверил, это объект.

Хорошо, спасибо, это тоже работает.

Ваш первый пример-это решение.

я попробовал:

        void Method ( object value )	{		IDictionary dic = value as IDictionary;		foreach ( var item in dic.Keys )		{			Debug.Log ( item );			Debug.Log ( dic [ item ] );		}	}


Но нет никакой необходимости использовать IDictionary type в качестве аргумента, просто замените его object. и я приму ваше решение.

Mehdi Gholam

Да

EmpireWorld

Ваш первый пример-это решение. пожалуйста, обновите его и сделайте так, чтобы он был похож на мой вопрос. я приму ваш вопрос.

Mehdi Gholam

Я бы сохранил IDictionary, так как компилятор поможет вам с ошибкой, если вы передадите что-то еще.

EmpireWorld

Пожалуйста, проверьте T SomeMethod< t> (); в вопросе, мне нужен рекурсивный метод.

Рейтинг:
0

Satya Prakash Swain

Надеюсь, я правильно понял вопрос. Объект словаря. Он работает без ошибок.

var dic = value as Dictionary<object,object>;


EmpireWorld

Как получить тип ключа словаря? в вашем коде тип ключа и значение оба являются объектом нет никакой разницы?!