Определение значения TypeOf атрибутов свойства в качестве имени существующего класса - PullRequest
0 голосов
/ 10 февраля 2020

Я пытаюсь перебрать классы, свойства которых не связаны с другими классами (например, publi c SomeOtherClass code {get; set;}

В своей попытке и благодаря советам других людей я пришел со следующим, который перебирает классы определенного c пространства имен (то есть Library = "ConsoleApp1.Library" et c) как:

        var classes = AppDomain.CurrentDomain.GetAssemblies ()
                                .SelectMany (t => t.GetTypes ())
                                .Where (t =>
                                            t.IsClass &&
                                            t.Namespace == Library &&
                                            !t.IsNested)
                                .ToList ();

и получает свойства как

        var properties = classes.SelectMany (x => x.GetProperties (BindingFlags.Public | BindingFlags.Instance)
                                .Select (y => y.PropertyType));

в то время как я получаю то, что мне нужно от foreach l oop:

        foreach ( var method in classes.Where 
                (x => !properties.Contains(x) && !properties.Contains (x))
                .Select (x => x.Name) )
        {
        // some work here
        }

Тем не менее, некоторые случаи проскальзывали через мой выбор, случаи, когда класс имеет следующие свойства как Array, ICollection, Список и словарь:

public class TopObject
{
    [JsonProperty("ex")]
    public OtherResults ex { get; set; }

    [JsonProperty ("Results")]
    public OtherResults Results { get; set; }

    private readonly OtherResults[,] Codes1 = new OtherResults[9, 9];
    public ICollection<OtherResults> Codes2 { get; set; }
    public List<OtherResults> Codes3 { get; set; }
    public Dictionary<int, OtherResults> Map { get { return _map; } }

    public TopObject()
    { Results = new OtherResults (); }
}

public class OtherResults
{
    [JsonProperty ("Jcodes")]
    public string Jcodes { get; set; }

    public OtherResults()
    { }
}

Мне нужна помощь в редактировании var method, чтобы включить (дополнительно) случаи, когда свойство имеет Dictionary Тип значения любого из классов или Array из тип любого из классов, или ICollection или List, которые принимают любые известные классы.

Пожалуйста, кто-то может помочь мне с этим? Большое спасибо

1 Ответ

1 голос
/ 11 февраля 2020

Так что я наконец-то успел немного поиграть с этим. Если я правильно понимаю, вы хотели бы что-то вроде этого:

Сначала мы создаем вспомогательную функцию, которая извлекает все ссылочные типы:

public static IEnumerable<Type> GetReferencedTypes(Type type)
{
    if (type.IsArray)
        return new List<Type> { type, type.GetElementType() };
    if (type.IsGenericType)
        return type.GetGenericArguments().SelectMany(GetReferencedTypes)
            .Union(new List<Type>{type});
    return new List<Type>{ type };
}

Я не могу гарантировать, что это охватывает все, но по крайней мере это кажется, получить все ссылки из ваших примеров. Массив здесь особенный, он не является обобщенным c, но мы должны извлечь его базовый тип. Все типы c мы извлекаем рекурсивно. и если это не какой-либо из них, мы просто возвращаем заданный тип.

Так что с помощью этой вспомогательной функции мы можем теперь сделать что-то вроде этого:

var currentAssembly = typeof(Program).Assembly;

var currentAssemblyName = typeof(Program).Assembly.GetName().Name;

var types = currentAssembly.GetTypes();

var classes = types.Where(type => type.IsClass && !type.IsNested).ToList();

var referencedTypes = classes.SelectMany(c => c.GetProperties().SelectMany(p => GetReferencedTypes(p.PropertyType))).Where(type => type.Assembly.GetName().Name == currentAssemblyName).Select(type => type.Name)
    .Distinct().ToList();

Мы получаем текущую сборку. Получите все типы, затем поместите все свойства этих типов через нашу вспомогательную функцию, выберите их имя, удалите дубликаты и создайте список. Что приводит к:

["Method100Response201_01", "Method600Response100", "Method700Response100", "Method100Response404_01"]

Имейте в виду, что при смене скрипки public Method500Response100[,] Codes1 = new Method500Response100[9, 9]; не возвращается вызовом GetProperties() (у него нет { get; set; }).

Надежда это помогает

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...