拦截动态调用以避免 RuntimeBinderException
Intercept a dynamic call to avoid RuntimeBinderException
我想拦截对动态类型的调用,以避免调用的方法或 属性 不存在时出现 RuntimeBinderException。
例如:
class Foo {
bool IsFool{ get; set; }
}
...
dynamic d = new Foo();
bool isFool = d.IsFoo; //works fine
bool isSpecial = d.IsSpecial; //RuntimeBinderException
我想做的是在调用时创建不存在的 属性 或只是 return null。
编辑:我正在尝试做的项目是一个配置文件reader。所以我希望这可以避免尝试捕获或检查配置文件的每个 属性 是否存在。
除了像
这样在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;
根据您在 post 中的编辑;不确定这会有多优雅,但您可以在 App.Config
或 Web.Config
文件中定义一个 AppSetting
元素,例如
<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;
}
在这里找到答案:
我必须扩展 DynamicObject
并覆盖 TryInvokeMember
最简单的方法是将其转换为 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; }
}
我想拦截对动态类型的调用,以避免调用的方法或 属性 不存在时出现 RuntimeBinderException。 例如:
class Foo {
bool IsFool{ get; set; }
}
...
dynamic d = new Foo();
bool isFool = d.IsFoo; //works fine
bool isSpecial = d.IsSpecial; //RuntimeBinderException
我想做的是在调用时创建不存在的 属性 或只是 return null。
编辑:我正在尝试做的项目是一个配置文件reader。所以我希望这可以避免尝试捕获或检查配置文件的每个 属性 是否存在。
除了像
这样在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;
根据您在 post 中的编辑;不确定这会有多优雅,但您可以在 App.Config
或 Web.Config
文件中定义一个 AppSetting
元素,例如
<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;
}
在这里找到答案:
我必须扩展 DynamicObject
并覆盖 TryInvokeMember
最简单的方法是将其转换为 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; }
}