Перехватить динамический вызов, чтобы избежать 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; }
}