Я был доволен Переполнение стека .
я слушаю / наблюдают за немногими другими:
, Но постоянный пух MS/Google/Apple/Yahoo их не становится действительно старой.
я слушал пару Hanselminutes и мог бы начать слушать более регулярно.
я хотел бы найти немного, что соглашение с фактической разработкой программного обеспечения выходит и не только "техническая сплетня".
Вы можете определить, есть ли у объекта свойство, без необходимости использовать динамические функции C # 4.0 - вместо этого используя функции отражения, которые существуют уже некоторое время (я знаю, по крайней мере, .NET 2.0 , не уверен насчет <2.0)
PropertyInfo info = codeObject.getType().GetProperty(
"LinePragma",
BindingFlags.Public | BindingFlags.Instance
)
Если объект не имеет свойства, GetProperty () вернет null. Вы можете сделать то же самое для полей (GetField ()) и методов (GetMethod ()).
Не только это, но когда у вас есть PropertyInfo, вы можете использовать его напрямую для выполнения своего набора:
info.SetValue(codeObject, new CodeLinePragma(), null);
Если вы не уверен, есть ли у свойства метод set, вы можете выбрать еще более безопасный путь:
MethodInfo method = info.GetSetMethod();
if(method != null)
method.Invoke(codeObject, new object[]{ new CodeLinePragma() });
Это также дает вам дополнительное преимущество в виде немного большей производительности по сравнению с накладными расходами на поиск динамического вызова (не удается найти ссылку для это утверждение, так что я просто выложу его там).
Я полагаю, что это не так ' Я отвечу на ваш вопрос напрямую, это скорее альтернативное решение для достижения той же цели. На самом деле я еще не использовал возможности # 4.0 (хотя я большой поклонник динамической типизации, доступной в Ruby). Это, конечно, не такое чистое / читаемое, как динамическое решение, но если вы не хотите создавать исключение, это может быть выход.
РЕДАКТИРОВАТЬ: как указывает @arbiter, «Это действительно только для нативного. чистые динамические объекты. Это не будет работать, например, для IDispatch. "
Я только что потратил почти час на поиск способов получить какой-нибудь метод "RespondTo" в стиле рубина на динамике. Конечно, нет простого ответа, но я еще не сдался.
Следует попробовать то, что было сказано при размышлении.
С динамикой единственное, что я пока получил, - это метод расширения который рассматривает ваш объект как динамический. Если работает, то работает, если нет - тихо выходит из строя ...
public static void Dynamight<T>(this T target, Action<dynamic> action)
{
dynamic d = target;
try
{
action(d);
}
catch (RuntimeBinderException)
{
//That was that, didn't work out
}
}
Тогда вы можете сделать ...
string h = "Hello";
h.Dynamight(d => Console.WriteLine(d.Length)); //Prints out 5
h.Dynamight(d => d.Foo()); //Nothing happens
Обновление:
Поскольку я получаю отрицательные голоса и что-то еще, позвольте мне быть более кратким, чем тонкое название метода расширения: Это динамит (Geddit?)! Жрать исключения и ничего не делать - это плохо . Это не производственный код, а первая версия апробации концепции. Я все время забываю, что ты можешь » на многотысячном форуме, например, на stackoverflow. Mea culpa.
Подумайте об этом: поскольку целевой класс может предоставить свою собственную реализацию для поиска членов и вызова для не- существующие члены (путем реализации IDynamicObject или создания подкласса DynamicObject) единственный способ проверить, существует ли член , - это вызвать его и посмотреть, обрабатывает ли объект его или генерирует исключение .
Еще раз, обработка несуществующих членов ДИНАМИЧЕСКАЯ!
- РЕДАКТИРОВАТЬ -
Если вы управляете созданием объекта, вы можете создать подкласс класса и реализовать IDynamicObject, чтобы сообщить другому классу, что метод не существует .
Несправедливо отрицать ответ, если он указывает на правду - то есть , что есть ' s нет и не может быть надежным способом проверки существования члена в среде динамической диспетчеризации , кроме вызова члена .
Я собираюсь вмешаться и сказать, что статическая типизация позволит избежать этой проблемы.
Это кандидат на абстрактный метод с переопределением.