我有一个动态对象,我认为它是用Clay实现的。它有两个可能的属性名之一。我想使用任何可用的属性名。
dynamic workItemPart = item.WorkItem; // is an Orchard.ContentManagement.ContentPart
var learnMore = workItemPart.LearnMore ?? workItemPart.LearnMoreField;
抛出一个Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
:
不包含'LearnMore'的定义
我们如何检查动态Clay对象是否具有属性?例如,在JavaScript中,我们可以这样做:
var workItemPart = {
LearnMoreField: "Sure"
}
console.log(workItemPart.LearnMore || workItemPart.LearnMoreField);
在c#和Clay中有这么简洁的东西吗?相关:Orchard.ContentManagement.ContentPart是用Clay实现的吗?
https://twitter.com/bleroy/status/497078654405312512您也可以使用索引方法:
var learnMore = workItemPart["LearnMore"] != null ?
workItemPart.LearnMore : workItemPart.LearnMoreField;
希望对你有帮助。
我不知道为什么没有。这两种方法都应该有效。
dynamic New = new ClayFactory();
var person = New.Person();
person.skill = "Outstanding";
var talent = person.talent;
var talentTwo = person["talent"];
var skill = person.talent ?? person.skill;
Console.WriteLine(skill);
skill = person.skill ?? person.talent;
Console.WriteLine(skill);
也许是Orchard扔给你一个曲线球…
有趣的是,空合并操作符没有正确处理第一个测试用例。但是,标准测试成功:
skill = person.talent != null ? person.talent : person.skill;
Console.WriteLine(skill);
不知道现在该给你什么建议
您可以使用扩展方法来检查属性是否存在:
public static class Extensions
{
public static bool HasProperty(this object d, string propertyName)
{
return d.GetType().GetProperty(propertyName) != null;
}
}
用法:
bool hasProperty = Extensions.HasProperty(workItemPart, "LearnMore");
var learnMore = hasProperty ? workItemPart.LearnMore : workItemPart.LearnMoreField;
它看起来不像一个扩展方法。由于workItemPart
是动态的,您需要通过指定类名显式地调用它。
@Shaun Luttin,在Orchard cms的背景下,这是一个相当老的问题,但最近我提出了这个已提交的pull request
所以,现在你可以使用下面的代码而不会抛出异常 if (contentItem.SomePart != null)
if (part.SomeField != null)
ContentItem和ContentPart类继承了System.Dynamic.DynamicObject并覆盖了TryGetMember()方法。在此之前,如果没有找到属性,该方法返回false
return false;
现在,即使结果对象(方法的out参数)被设置为null,该方法也会返回true,从而防止抛出异常
result = null;
return true;
详情请参阅上面的相关PR链接
最好