Как мы проверяем, имеет ли динамический глиняный объект свойство?

У меня есть динамический объект, который, я думаю, реализован с помощью глины. У него есть одно из двух возможных имен свойств. Я хочу использовать любое доступное имя свойства. Следующее не работает:

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 реализован с помощью глины?

https://twitter.com/bleroy/status/497078654405312512

3 ответа

Вы также можете использовать индексированный подход:

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

Может быть, это Орчард бросает тебе мяч...

Интересно, что оператор null-coalesce неправильно обрабатывает первый тестовый пример. Тем не менее, стандартный тест проходит успешно:

        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, довольно старая проблема в контексте CMS Orchard, но недавно я предложил этот запрос на получение, который был передан

Итак, теперь вы можете использовать следующее без исключения

    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 выше

Лучший

Другие вопросы по тегам