C#带递归的反射

Sye*_*eer 5 c# reflection recursion nested nested-class

我正在研究Reflection,但我在执行递归时遇到困难.

代码:

public class User {
  public string Name;
  public int Number;
  public Address Address;    
}


public class Address {
 public string Street;
 public string State;
 public string Country;
}
Run Code Online (Sandbox Code Playgroud)

现在我正在打印价值观.

 Type t = user.GetType();  
 PropertyInfo[] props = t.GetProperties(); 
 foreach (PropertyInfo prp in props)  
 {  
   if(!prp.GetType().IsPrimitive && prp.GetType().IsClass) 
   {
     // Get the values of the Inner Class.
     // i am stucked over here , can anyone help me with this.

           Type ty = prp.GetType();
           var prpI = ty.GetProperties();
           //var tp = ty.GetType().;
            foreach (var propertyInfo in prpI)
            {
            var value = propertyInfo.GetValue(prp);
            var stringValue = (value != null) ? value.ToString() : "";
            console.WriteLine(prp.GetType().Name + "." + propertyInfo.Name+" Value : " +stringValue);    
            }
   }
   else
   {    
     var value = prp.GetValue(user);   
     var stringValue = (value != null) ? value.ToString() : "";
     console.writeline(user.GetType().Name + "." + prp.Name+" Value : " +stringValue); 
   }
 }
Run Code Online (Sandbox Code Playgroud)

我想知道如何找出属性是类还是原语.并且如果它是一个类,则进行递归.

slo*_*oth 13

首先,如果要访问类型的属性,请确保使用具有以下属性的类型:

public class User {
  public string Name{get;set;}
  public int Number{get;set;}
  public Address Address{get;set;}    
}


public class Address {
 public string Street{get;set;}
 public string State{get;set;}
 public string Country{get;set;}
}
Run Code Online (Sandbox Code Playgroud)

第二,prp.GetType()永远回归PropertyInfo.您正在寻找prp.PropertyType,它将返回该属性的类型.

此外,if(!prp.GetType().IsPrimitive && prp.GetType().IsClass)不会按照您想要的方式工作,因为String例如是一个类,也不是原始的.更好用prp.PropertyType.Module.ScopeName != "CommonLanguageRuntimeLibrary".

最后但并非最不重要的是,要使用递归,您实际上必须将代码放入方法中.

这是一个完整的例子:

IEnumerable<string> GetPropertInfos(object o, string parent=null)
{
    Type t = o.GetType();  
    PropertyInfo[] props = t.GetProperties(BindingFlags.Public|BindingFlags.Instance);
    foreach (PropertyInfo prp in props)  
    {  
        if(prp.PropertyType.Module.ScopeName != "CommonLanguageRuntimeLibrary")
        {
            // fix me: you have to pass parent + "." + t.Name instead of t.Name if parent != null
            foreach(var info in GetPropertInfos(prp.GetValue(o), t.Name))
                yield return info; 
        }
        else
        {    
            var value = prp.GetValue(o);   
            var stringValue = (value != null) ? value.ToString() : "";
            var info = t.Name + "." + prp.Name + ": " + stringValue;
            if (String.IsNullOrWhiteSpace(parent))
                yield return info; 
            else
                yield return parent + "." + info; 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

像这样使用:

var user = new User { Name = "Foo", Number = 19, Address = new Address{ Street="MyStreet", State="MyState",  Country="SomeCountry" }    };
foreach(var info in GetPropertInfos(user))
    Console.WriteLine(info);
Run Code Online (Sandbox Code Playgroud)

它会输出

User.Name: Foo
User.Number: 19
User.Address.Street: MyStreet
User.Address.State: MyState
User.Address.Country: SomeCountry
Run Code Online (Sandbox Code Playgroud)

  • 感谢一吨兄弟,输出完全符合我的需要,非常出色,从早上开始我就一直在挠头,只想说一个大感谢。 (2认同)