简体   繁体   English

拦截动态调用以避免RuntimeBinderException

[英]Intercept a dynamic call to avoid RuntimeBinderException

I want to intercept calls to a dynamic type to avoid a RuntimeBinderException when the method or property called does not exist. 当调用的方法或属性不存在时,我想拦截对动态类型的调用以避免RuntimeBinderException。 For example: 例如:

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

What I want to do is to either create the nonexistent property when called or to just return null. 我想做的就是在调用时创建不存在的属性,或者只返回null。

EDIT : The project I'm trying to do is a configuration file reader. 编辑 :我想做的项目是一个配置文件阅读器。 So I want this to avoid doing a try catch or check if exists to every property of the cofiguration file. 因此,我希望这避免尝试尝试捕获或检查配置文件的每个属性是否存在。

I don't see any special way than handling in try .. catch block like 除了在try .. catch块中进行处理外,我看不到任何特殊方法

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

(OR) Using System.Reflection namespace (OR)使用System.Reflection命名空间

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

Per your edit in post; 根据您的帖子编辑; not sure how elegant this would be but you can define a AppSetting element in App.Config or Web.Config file like 不知道这有多优雅,但是您可以在App.ConfigWeb.Config文件中定义一个AppSetting元素,例如

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

Then can read that to verify whether the member exists or not and then call accordingly 然后可以读取该内容以验证成员是否存在,然后进行相应的调用

        dynamic d = new Foo();

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

Exception usualy take much time try to check if property exist: 通常,异常会花费大量时间尝试检查属性是否存在:

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

Found the answer here: https://stackoverflow.com/a/1110504/818088 在这里找到答案: https : //stackoverflow.com/a/1110504/818088
I have to extend the DynamicObject and override TryInvokeMember 我必须扩展DynamicObject并覆盖TryInvokeMember

Easiest way is to convert it into a JSON dynamic object: 最简单的方法是将其转换为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; }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM