Как я могу получить значение свойства от анонимного типа?

Этот код, основанный на здесь , будет правильно поднять KeyboardInterrupt и EOFError, если нажаты клавиши Ctrl + C или Ctrl + D.

Должно работать в Windows и Linux. Версия ОС X доступна из исходного источника.

class _Getch:
    """Gets a single character from standard input.  Does not echo to the screen."""
    def __init__(self):
        try:
            self.impl = _GetchWindows()
        except ImportError:
            self.impl = _GetchUnix()

    def __call__(self): 
        char = self.impl()
        if char == '\x03':
            raise KeyboardInterrupt
        elif char == '\x04':
            raise EOFError
        return char

class _GetchUnix:
    def __init__(self):
        import tty
        import sys

    def __call__(self):
        import sys
        import tty
        import termios
        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(sys.stdin.fileno())
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
        return ch


class _GetchWindows:
    def __init__(self):
        import msvcrt

    def __call__(self):
        import msvcrt
        return msvcrt.getch()


getch = _Getch()

20
задан Sailing Judo 17 May 2009 в 16:27
поделиться

5 ответов

Вы когда-нибудь пробовали использовать отражение? Вот пример фрагмента кода:

// use reflection to retrieve the values of the following anonymous type
var obj = new { ClientId = 7, ClientName = "ACME Inc.", Jobs = 5 }; 
System.Type type = obj.GetType(); 
int clientid = (int)type.GetProperty("ClientId").GetValue(obj, null);
string clientname = (string)type.GetProperty("ClientName").GetValue(obj, null);

// use the retrieved values for whatever you want...
47
ответ дан 29 November 2019 в 22:26
поделиться

Одна из проблем с анонимными типами в том, что их сложно использовать между функциями. Невозможно «назвать» анонимный тип, и, следовательно, очень сложно переключаться между ними. Это предотвращает их использование в качестве выражения типа для всего, что появляется в метаданных и определяется пользователем.

Я не могу точно сказать, какой API вы используете выше. Однако API не может возвращать строго типизированный анонимный тип, поэтому я предполагаю, что selectedObject типизирован как object. C # 3.0 и ниже не поддерживает динамический доступ, поэтому вы не сможете получить доступ к идентификатору свойства, даже если он доступен во время выполнения.

Вам понадобится одно из следующих действий, чтобы обойти это

  • Использовать отражение, чтобы захватить свойство
  • Создать полный тип и использовать его для заполнения сетки данных
  • Используйте одно из множества хакерских приведения анонимных типов

РЕДАКТИРОВАТЬ

Вот пример того, как взломать анонимное приведение типа

public T AnonymousTypeCast<T>(object anonymous, T typeExpression) { 
  return (T)anonymous;
}

...
object obj = GetSomeAnonymousType();
var at = AnonymousTypeCast(obj, new { Name = String.Empty, Id = 0 });

Причина, по которой это хакерство, в том, что это очень легко сломать. Например, в методе, в котором изначально создается анонимный тип. Если я добавлю еще одно свойство к типу, приведенный выше код будет компилироваться, но не удастся во время выполнения.

17
ответ дан 29 November 2019 в 22:26
поделиться

Как правильно предположил JaredPar, типом возвращаемого значения GetRow () является объект . При работе с сеткой DevExpress вы можете извлечь желаемое значение следующим образом:

int clientId = (int)gridView.GetRowCellValue(rowHandle, "ClientId");

Этот подход имеет такие же недостатки, как и описанные ранее «хакерские анонимные преобразования типов»: вам нужна волшебная строка для идентификации столбца плюс тип, приведенный из объекта на внутр.

1
ответ дан 29 November 2019 в 22:26
поделиться

Это может быть неправильно (у вас может не хватить кода), но разве вам не нужно индексировать строку, чтобы вы выбирали, какой столбец вам нужен? Или, если «Id» - это столбец, который вам нужен, вы должны сделать что-то вроде этого:

var selectedObject = view.GetRow(rowHandle);
_selectedId = selectedObject["Id"];

Вот как я бы получил содержимое столбца в сетке данных. Теперь, если сам столбец является анонимным типом, я не знаю, но если вы просто получаете именованный столбец с примитивным типом, тогда это должно работать.

0
ответ дан 29 November 2019 в 22:26
поделиться

Когда я работал с передачей анонимных типов и пытался их преобразовать, мне, в конце концов, было легче написать оболочку, которая обрабатывала бы работу с объектом. Вот ссылка на сообщение об этом в блоге.

http://somewebguy.wordpress.com/2009/05/29/anonymous-types-round-two/

В конечном итоге ваш код будет выглядеть примерно так .

//create an anonymous type
var something = new {  
  name = "Mark",  
  age = 50  
};  
AnonymousType type = new AnonymousType(something);

//then access values by their property name and type
type.With((string name, int age) => {  
  Console.Write("{0} :: {1}", name, age);  
}); 

//or just single values
int value = type.Get<int>("age");   
3
ответ дан 29 November 2019 в 22:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: