Перехватить динамический вызов, чтобы избежать RuntimeBinderException

Я хочу перехватывать вызовы динамического типа, чтобы избежать RuntimeBinderException, когда вызываемый метод или свойство не существует. Например:

class Foo {
    bool IsFool{ get; set; }
}
...
dynamic d = new Foo();
bool isFool = d.IsFoo; //works fine
bool isSpecial = d.IsSpecial; //RuntimeBinderException

То, что я хочу сделать, это либо создать несуществующее свойство при вызове, либо просто вернуть ноль.

РЕДАКТИРОВАТЬ: проект, который я пытаюсь сделать, является читатель файла конфигурации. Так что я хочу, чтобы это не делало попытку перехвата или проверки наличия каждого свойства файла конфигурации.

3 ответа

Решение

Нашел ответ здесь: /questions/17582962/obrabotka-metoda-c-kotoryij-ne-opredelen-dlya-dinamicheskogo-obekta-on-zhe-responsetomethodmissing/17582973#17582973
Я должен продлить DynamicObject и переопределить TryInvokeMember

Я не вижу особого пути, чем обработка в try .. catch блок как

try 
{
  bool isSpecial = d.IsSpecial;
  return isSpecial;
}
catch(RuntimeBinderException)
{
  // do something else
  return false;
}

(ИЛИ) Использование System.Reflection Пространство имен

        bool isSpecial = typeof(Foo)
                         .GetProperties()
                         .Select(p => p.Name == "IsSpecial").Count() > 0 
                         ? d.IsSpecial : false;

За ваши изменения в посте; не уверен, насколько это будет элегантно, но вы можете определить AppSetting элемент в App.Config или же Web.Config файл как

<configuration>
  <appSettings>
    <add key="IsFool" value="Foo"/>
    <add key="Display" value="Foo"/>
  </appSettings>
</configuration>

Затем можете прочитать это, чтобы проверить, существует ли член или нет, а затем вызвать соответственно

        dynamic d = new Foo();

        bool isSpecial = System.Configuration.ConfigurationManager.AppSettings
                         .AllKeys.Contains("IsSpecial") 
                         ? d.IsSpecial : false;

Исключение обычно занимает много времени, пытаясь проверить, существует ли свойство:

public static bool HasProperty(this object obj, string propertyName)
{
    return obj.GetType().GetProperty(propertyName) != null;
}

Самый простой способ - преобразовать его в динамический объект JSON:

public static class JsonExtensions
{
    public static dynamic ToJson(this object input) => 
         System.Web.Helpers.Json.Decode(System.Web.Helpers.Json.Encode(input));

    static int Main(string[] args) {
         dynamic d = new Foo() { IsFool = true }.ToJson();
         Console.WriteLine(d.IsFool); //prints True
         Console.WriteLine(d.IsSpecial ?? "null"); //prints null
    }
}

class Foo
{
    public bool IsFool { get; set; }
}
Другие вопросы по тегам