我的情况很简单。在我的代码中,我有这样的代码:

dynamic myVariable = GetDataThatLooksVerySimilarButNotTheSame();

//How to do this?
if (myVariable.MyProperty.Exists)   
//Do stuff

因此,基本上我的问题是如何检查(不抛出异常)某个属性在我的动态变量上是可用的。我可以使用GetType(),但我宁愿避免这样做,因为我并不真正需要知道对象的类型。我真正想知道的是是否有一个属性(或方法,如果这使工作更简单的话)可用。指针吗?


当前回答

以防它能帮到别人:

如果GetDataThatLooksVerySimilarButNotTheSame()方法返回一个ExpandoObject,你也可以在检查之前将其转换为dictionary。

dynamic test = new System.Dynamic.ExpandoObject();
test.foo = "bar";

if (((IDictionary<string, object>)test).ContainsKey("foo"))
{
    Console.WriteLine(test.foo);
}

其他回答

我在单元测试中遇到过类似的问题。

使用SharpTestsEx可以检查属性是否存在。我使用这个测试我的控制器,因为JSON对象是动态的,有人可以更改名称,而忘记在javascript中更改它或其他东西,所以在编写控制器时测试所有属性应该增加我的安全性。

例子:

dynamic testedObject = new ExpandoObject();
testedObject.MyName = "I am a testing object";

现在,使用SharTestsEx:

Executing.This(delegate {var unused = testedObject.MyName; }).Should().NotThrow();
Executing.This(delegate {var unused = testedObject.NotExistingProperty; }).Should().Throw();

使用这个,我测试所有现有的属性使用“Should(). notthrow()”。

这可能离题了,但对某人来说可能有用。

如果你控制的类型被用作动态,你不能返回一个元组而不是每个属性访问的值吗?之类的……

public class DynamicValue<T>
{
    internal DynamicValue(T value, bool exists)
    {
         Value = value;
         Exists = exists;
    }

    T Value { get; private set; }
    bool Exists { get; private set; }
}

可能是一个幼稚的实现,但如果您每次都在内部构造其中一个,并返回该值而不是实际值,那么您可以在每个属性访问上检查Exists,如果值为默认值(T),则单击value(如果不为默认值,则不相关)。

也就是说,我可能会遗漏一些动态工作原理的知识,这可能不是一个可行的建议。

对我来说,这是可行的:

if (IsProperty(() => DynamicObject.MyProperty))
  ; // do stuff



delegate string GetValueDelegate();

private bool IsProperty(GetValueDelegate getValueMethod)
{
    try
    {
        //we're not interesting in the return value.
        //What we need to know is whether an exception occurred or not

        var v = getValueMethod();
        return v != null;
    }
    catch (RuntimeBinderException)
    {
        return false;
    }
    catch
    {
        return true;
    }
}

也许使用反射?

dynamic myVar = GetDataThatLooksVerySimilarButNotTheSame();
Type typeOfDynamic = myVar.GetType();
bool exist = typeOfDynamic.GetProperties().Where(p => p.Name.Equals("PropertyName")).Any(); 

在我的例子中,我需要检查具有特定名称的方法是否存在,因此我使用了一个接口

var plugin = this.pluginFinder.GetPluginIfInstalled<IPlugin>(pluginName) as dynamic;
if (plugin != null && plugin is ICustomPluginAction)
{
    plugin.CustomPluginAction(action);
}

此外,接口可以包含的不仅仅是方法:

接口可以包含方法、属性、事件、索引器等等 这四种成员类型的组合。

来自:Interfaces (c#编程指南)

优雅,不需要陷阱异常或发挥反射…