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

dynamic myVariable = GetDataThatLooksVerySimilarButNotTheSame();

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

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


当前回答

也许使用反射?

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

其他回答

下面是另一种方法:

using Newtonsoft.Json.Linq;

internal class DymanicTest
{
    public static string Json = @"{
            ""AED"": 3.672825,
            ""AFN"": 56.982875,
            ""ALL"": 110.252599,
            ""AMD"": 408.222002,
            ""ANG"": 1.78704,
            ""AOA"": 98.192249,
            ""ARS"": 8.44469
}";

    public static void Run()
    {
        dynamic dynamicObject = JObject.Parse(Json);

        foreach (JProperty variable in dynamicObject)
        {
            if (variable.Name == "AMD")
            {
                var value = variable.Value;
            }
        }
    }
}

也许使用反射?

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

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

使用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()”。

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

对我来说,这是可行的:

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;
    }
}

我认为没有办法在不尝试访问动态变量的情况下发现动态变量是否有某个成员,除非你在c#编译器中重新实现动态绑定的处理方式。这可能包含很多猜测,因为根据c#规范,它是由实现定义的。

所以你应该尝试访问成员并捕获异常,如果它失败了:

dynamic myVariable = GetDataThatLooksVerySimilarButNotTheSame();

try
{
    var x = myVariable.MyProperty;
    // do stuff with x
}
catch (RuntimeBinderException)
{
    //  MyProperty doesn't exist
}