Отражение C # - Как я могу сказать, если объект o имеет тип KeyValuePair, а затем привести его? - PullRequest
10 голосов
/ 28 апреля 2010

В настоящее время я пытаюсь написать метод Dump () из LinqPad, эквивалентный iin C #, для собственного удовольствия. Я перехожу с Java на C #, и это скорее упражнение, чем требование бизнеса. У меня почти все работает, кроме Dumping a Dictionary.

Проблема в том, что KeyValuePair является типом значения. Для большинства других типов значений я просто вызываю метод ToString, но этого недостаточно, поскольку KeyValuePair может содержать Enumerables и другие объекты с нежелательными методами ToString. Поэтому мне нужно разобраться, если это KeyValuePair, а затем разыграть его. В Java я мог бы использовать универсальные шаблоны для этого, но я не знаю эквивалента в C #.

Ваш квест, заданный для объекта o, определяет, является ли он KeyValuePair, и вызывает Print для его ключа и значения.

Print(object o) {
   ...
}

Спасибо!

Ответы [ 3 ]

33 голосов
/ 28 апреля 2010

Если вы не знаете типы, хранящиеся в 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 голос
/ 28 апреля 2010

Предполагая, что вы используете универсальную 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, вам нужно использовать отражение. А ты?

0 голосов
/ 28 апреля 2010

у вас есть ключевое слово http://msdn.microsoft.com/es-es/library/scekt9xw(VS.80).aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...