C # Проверка и вызов свойств объекта, которые могут или не могут существовать - PullRequest
0 голосов
/ 19 октября 2019

Создавая доказательство концепции, я получил большую часть ее решения, это только последний шаг моего доказательства концепции, и я бью кирпичную стену. Я строю автоматический конструктор для левой навигации на ASP.net со страницами Razor на основе определенных определений, содержащихся на странице. Идея - это универсальная навигационная панель вверху, а для страницы - навигационная панель слева.

    List<object> navElements = new List<object> {
        new {text = "Test1", location = "test1", subElements = new List<object> {
            new {text = "Test1-1", location = "test1-1", subElements = new List<object> {
                new {text = "Test1-1-1", location = "test1-1-1"},
                new {text = "Test1-1-2", location = "test1-1-2"},
                new {text = "Test1-1-3", location = "test1-1-3"}
            } },
            new {text = "Test1-2", location = "test1-2", subElements = new List<object> {
                new {text = "Test1-2-1", location = "test1-2-1"},
                new {text = "Test1-2-2", location = "test1-2-2"},
                new {text = "Test1-2-3", location = "test1-2-3"}
            } },
            new {text = "Test1-3", location = "test1-3", subElements = new List<object> {
                new {text = "Test1-3-1", location = "test1-3-1"},
                new {text = "Test1-3-2", location = "test1-3-2"},
                new {text = "Test1-3-3", location = "test1-3-3"}
            } }

        } }
    };

Обратите внимание, что это определение теста пытается углубиться в три уровня. Я построил рекурсивную функцию для захвата каждого слоя подэлементов, содержащихся в списке. Проблема заключается в том, что, поскольку subElement не существует на последнем слое, он выдает 'object' does not contain a definition for 'subElements' and no accessible extension method 'subElements' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)

. Он может найти как универсальные свойства (текст и местоположение).

Found thisВопрос о стеке , в котором предлагалось использовать OBJECT.GetType().GetProperty("PROPERTYNAME") != null, и который, кажется, работает просто отлично, однако я все еще не могу скомпилировать при вызове этого свойства после этого блока if.

Как я могу проверитьfor и вызывать переменно существующее свойство внутри универсального объекта?

Эта проверка должна быть уловлена ​​для двух действий:

  1. Назначает необходимый код таблицы стилей, чтобы в раскрывающемся спискекаждый слой. Поскольку наличие выпадающего списка зависит от существования подслоя.
  2. Для запуска рекурсии нижних уровней. Это позволило бы бесконечные слои выпадающих окон, так как он функционирует.

Вот общий вид функционализированного компоновщика.

@{
    void navLeftBuilder(List<object> elements)
    {
        foreach (object element in elements)
        {
            @if (element.subElements) { navLeftBuilder(element.subElement); }
        }
    }
}

Я даже пытался изменить вызов объекта на

@{
    void navLeftBuilder(List<object> elements)
    {
        object obj;
        foreach (int element in elements)
        {
            obj = elements[element];
            @if (obj.subElements) { navLeftBuilder(obj.subElement); }
        }
    }
}

1 Ответ

0 голосов
/ 19 октября 2019

Попробуйте что-то вроде следующего:

class NavElement { 
        public string Text { get; set; }
        public string Location { get; set; }

        public List<NavElement> SubElements { get; set; }
    }

    private static void Main()
    {
        List<NavElement> navElements = new List<NavElement> {
        new NavElement{Text = "1", Location = "1", SubElements = new List<NavElement> {
            new NavElement{Text = "1-1", Location = "1-1", SubElements = new List<NavElement> {
                new NavElement{Text = "1-1-1", Location = "1-1-1"},
                new NavElement {Text = "1-1-2", Location = "1-1-2"},
                new NavElement {Text = "1-1-3", Location = "1-1-3"}
            } },
            new NavElement {Text = "1-2", Location = "1-2", SubElements = new List<NavElement> {
                new NavElement {Text = "1-2-1", Location = "1-2-1"},
                new NavElement {Text = "1-2-2", Location = "1-2-2"},
                new NavElement {Text = "1-2-3", Location = "1-2-3"}
            } },
            new NavElement {Text = "1-3", Location = "1-3", SubElements = new List<NavElement> {
                new NavElement {Text = "1-3-1", Location = "1-3-1"},
                new NavElement {Text = "1-3-2", Location = "1-3-2"},
                new NavElement {Text = "1-3-3", Location = "1-3-3"}
            } }
        } }
        };

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

Console.WriteLine(navElements[0].SubElements[2].SubElements[2].Text); 

напечатает

1-3-3

РЕДАКТИРОВАТЬ

Для записи это то, что будет работать, но то, что вы должны НЕ до.

void navLeftBuilder(List<dynamic> elements)
{
    foreach (dynamic element in elements)
    {
        Console.WriteLine($"I'm '{element.text}'");
        try
        {
            navLeftBuilder(element.subElements);
        }
        catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)
        {
            //  property doesn't exist, ignore
        }
    }
}
...