简体   繁体   English

如何获得在Roslyn的类中使用的整个类型? (所有嵌套/内部类型递归)

[英]How to get whole types that is used in a class with Roslyn? (all nested/inner types recursively)

Please consider this sample: 请考虑以下示例:

public class Person
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public float Age { get; set; }
    public List<Address> Addresses { get; set; }
    public IEnumerable<Job> Jobs { get; set; }
    public IInterface MyInterface { get; set; }
}

public class Address
{
    public string City { get; set; }
    public string[] Phones { get; set; }
    public MyEnum E1  { get; set; }
}

public class Job
{
    public Dictionary<decimal, Address> A1 { get; set; }
    public Collection<DateTime> Date { get; set; }
    public Tuple<double, BigInteger> A2 { get; set; }
}

public enum MyEnum
{
   En1,
   En2
}

As you see, I want to get all inner classes/structs/types of Person so the result is : 如您所见,我想获取Person所有内部类/结构/类型,因此结果是:

Person.GetInnerTypes():

Guid
float
string
IInterface
Address
string[]
MyEnum
Job
List<Address>
IEnumerable<Job>
Dictionary<decimal, Address>
decimal
Collection<DateTime>
DateTime
Tuple<double, BigInteger>
double
BigInteger

The types are collected from everywhere (properties, arguments,...) 这些类型是从任何地方收集的(属性,参数等)

Is it possible to find whole types (recursively) by Roslyn? Roslyn是否可以(递归)找到整个类型? Does anyone have an idea? 有人有主意吗?

EDIT: 编辑:

Why do I need this? 我为什么需要这个?

The problem comes from creating a code generator, if you see the Bogus library you should define rules for every type at first then create the main rule for Person class so I need to know all types for a class to create a code generator for generating test data! 问题来自创建代码生成器,如果您看到Bogus库,则应首先为每种类型定义规则,然后为Person类创建主规则,因此我需要知道一个类的所有类型,才能创建用于生成测试的代码生成器数据! (generate a working class) (产生工人阶级)

EDIT 2: 编辑2: 在此处输入图片说明

That's a very broad answer. 这是一个非常广泛的答案。 If you are interested in the properteis only - just use this question. 如果您仅对属性感兴趣,请使用问题。 Find your class' DeclarationSyntax, then find all DescendantNodes of PropertyDeclarationSyntax type. 找到您的类的DeclarationSyntax,然后找到PropertyDeclarationSyntax类型的所有DescendantNodes。 PropertyDeclarationSyntax will give you access to types, and you will go into recursion (don't forget about loops). PropertyDeclarationSyntax将使您可以访问类型,并且可以进行递归(不要忘记循环)。 This should be enough for a prototype. 这对于一个原型应该足够了。

Even on this step you should be careful with 即使在这一步,您也应注意

  1. Nested classes. 嵌套类。 Types used there will be included into your list too. 那里使用的类型也将包括在您的列表中。
  2. Generics. 泛型。 Sometime there are limitations like Type where T : ISomeInterface. 有时会有一些限制,例如Type where T:ISomeInterface。 Also, nested Generics. 另外,嵌套泛型。
  3. Partial classes 部分课程
  4. Is Func < T1, T2> the same with Func< T2, T1> for you? Func <T1,T2>是否与Func <T2,T1>一样?

After all, there are questions about your problem itself. 毕竟,您的问题本身就有疑问。

  1. Do you need parents of used types? 您需要二手类型的父母吗?
  2. Do you care about properties only, or methods\\fields\\events etc are valuable also? 您只在乎属性,还是方法,字段,事件等也很有价值?
  3. Should you think about properties inherited from the parents? 您是否应该考虑从父母那里继承的财产?
  4. If you care about methods - should you think about parameters types? 如果您关心方法-您应该考虑参数类型吗?
  5. If you care about methods - should you think about variables defined inside? 如果您关心方法-您应该考虑内部定义的变量吗?

Edit1. 编辑1。 Maybe reflection is enough for your task? 也许反思足以完成您的任务?

static void Main(string[] args)
    {
        var properties = typeof(DemoPerson).GetProperties();
        foreach(var property in properties)
        {
            Console.WriteLine($"Property: {property.Name}\tType: {property.PropertyType}");
        }

        Console.ReadLine();
    }

    public class DemoPerson
    {
        public Guid Id { get; set; }
        public string Name { get; set; }            
        public List<DemoAddress> Addresses { get; set; }            
    }

    public class DemoAddress
    {
        public string City { get; set; }            
    }

With output 带输出

Property: Id Type: System.Guid 属性:ID类型:System.Guid

Property: Name Type: System.String 属性:名称类型:System.String

Property: Addresses Type: System.Collections.Generic.List`1[DemoInnerTypes.Program+DemoAddress] 属性:地址类型:System.Collections.Generic.List`1 [DemoInnerTypes.Program + DemoAddress]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM