C# 4.0, обнаружьте, если метод отсутствует

Я был доволен Переполнение стека .

я слушаю / наблюдают за немногими другими:

, Но постоянный пух MS/Google/Apple/Yahoo их не становится действительно старой.

я слушал пару Hanselminutes и мог бы начать слушать более регулярно.

я хотел бы найти немного, что соглашение с фактической разработкой программного обеспечения выходит и не только "техническая сплетня".

7
задан Marnix van Valen 15 September 2011 в 09:57
поделиться

4 ответа

Вы можете определить, есть ли у объекта свойство, без необходимости использовать динамические функции 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. "

8
ответ дан 6 December 2019 в 19:41
поделиться

Я только что потратил почти час на поиск способов получить какой-нибудь метод "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.

5
ответ дан 6 December 2019 в 19:41
поделиться

Подумайте об этом: поскольку целевой класс может предоставить свою собственную реализацию для поиска членов и вызова для не- существующие члены (путем реализации IDynamicObject или создания подкласса DynamicObject) единственный способ проверить, существует ли член , - это вызвать его и посмотреть, обрабатывает ли объект его или генерирует исключение .

Еще раз, обработка несуществующих членов ДИНАМИЧЕСКАЯ!

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

Если вы управляете созданием объекта, вы можете создать подкласс класса и реализовать IDynamicObject, чтобы сообщить другому классу, что метод не существует .

Несправедливо отрицать ответ, если он указывает на правду - то есть , что есть ' s нет и не может быть надежным способом проверки существования члена в среде динамической диспетчеризации , кроме вызова члена .

-1
ответ дан 6 December 2019 в 19:41
поделиться

Я собираюсь вмешаться и сказать, что статическая типизация позволит избежать этой проблемы.

Это кандидат на абстрактный метод с переопределением.

-1
ответ дан 6 December 2019 в 19:41
поделиться
Другие вопросы по тегам:

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