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

时间:2018-04-10 17:54:11

标签: c# reflection .net-core roslyn

请考虑此示例:

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
}

如您所见,我想获得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

从各处收集类型(属性,参数,......)

是否可以通过Roslyn找到整个类型(递归)? 有没有人有想法?

修改

为什么我需要这个?

问题来自于创建代码生成器,如果你看到Bogus库,你应该首先为每个类型定义规则然后为Person类创建主规则,所以我需要知道类的所有类型创建一个代码生成器来生成测试数据! (生成工人阶级)

编辑2: enter image description here

1 个答案:

答案 0 :(得分:0)

这是一个非常广泛的答案。 如果您只对该属性感兴趣 - 请使用this问题。找到你的类'DeclarationSyntax,然后找到PropertyDeclarationSyntax类型的所有DescendantNodes。 PropertyDeclarationSyntax将为您提供对类型的访问,您将进入递归(不要忘记循环)。 这对于原型来说应该足够了。

即使在这一步,你也要小心

  1. 嵌套类。此处使用的类型也将包含在您的列表中。
  2. 泛型。有时会出现类型为T:ISomeInterface的限制。另外,嵌套Generics。
  3. 部分课程
  4. 是Func&lt; T1,T2>与Func相同T2,T1>为你?
  5. 毕竟,对你的问题本身存在疑问。

    1. 您是否需要使用过类型的父母?
    2. 您是否只关心属性,或者方法\字段\事件等是否也很有价值?
    3. 您是否应该考虑从父母那里继承的财产?
    4. 如果你关心方法 - 你应该考虑参数类型吗?
    5. 如果你关心方法 - 你应该考虑内部定义的变量吗?
    6. <强> EDIT1。 也许反射足以完成你的任务?

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

      带输出

      属性:Id类型:System.Guid

      属性:名称类型:System.String

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