Этот код, основанный на здесь , будет правильно поднять 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()
Вы когда-нибудь пробовали использовать отражение? Вот пример фрагмента кода:
// 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...
Одна из проблем с анонимными типами в том, что их сложно использовать между функциями. Невозможно «назвать» анонимный тип, и, следовательно, очень сложно переключаться между ними. Это предотвращает их использование в качестве выражения типа для всего, что появляется в метаданных и определяется пользователем.
Я не могу точно сказать, какой 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 });
Причина, по которой это хакерство, в том, что это очень легко сломать. Например, в методе, в котором изначально создается анонимный тип. Если я добавлю еще одно свойство к типу, приведенный выше код будет компилироваться, но не удастся во время выполнения.
Как правильно предположил JaredPar, типом возвращаемого значения GetRow ()
является объект
. При работе с сеткой DevExpress вы можете извлечь желаемое значение следующим образом:
int clientId = (int)gridView.GetRowCellValue(rowHandle, "ClientId");
Этот подход имеет такие же недостатки, как и описанные ранее «хакерские анонимные преобразования типов»: вам нужна волшебная строка для идентификации столбца плюс тип, приведенный из объекта на внутр.
Это может быть неправильно (у вас может не хватить кода), но разве вам не нужно индексировать строку, чтобы вы выбирали, какой столбец вам нужен? Или, если «Id» - это столбец, который вам нужен, вы должны сделать что-то вроде этого:
var selectedObject = view.GetRow(rowHandle);
_selectedId = selectedObject["Id"];
Вот как я бы получил содержимое столбца в сетке данных. Теперь, если сам столбец является анонимным типом, я не знаю, но если вы просто получаете именованный столбец с примитивным типом, тогда это должно работать.
Когда я работал с передачей анонимных типов и пытался их преобразовать, мне, в конце концов, было легче написать оболочку, которая обрабатывала бы работу с объектом. Вот ссылка на сообщение об этом в блоге.
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");