I am working on the Reflection , but i am stuck while doing the recursion.
Code :
public class User {
public string Name;
public int Number;
public Address Address;
}
public class Address {
public string Street;
public string State;
public string Country;
}
now i am printing the values.
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);
}
}
i want to know how to find out whether the property is a class or the primitive. and do the recursion if it is a class.
First of all, if you want to access the properties of a type, ensure you are using a type which has properties:
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;}
}
Second, prp.GetType()
will always return PropertyInfo
. You are looking for prp.PropertyType
, which will return the Type of the property.
Also, if(!prp.GetType().IsPrimitive && prp.GetType().IsClass)
won't work the way you want, because String
e.g. is a class and also not a primitive. Better use prp.PropertyType.Module.ScopeName != "CommonLanguageRuntimeLibrary"
.
Last but not least, to use recursion, you actually have to put your code into a method.
Here's a complete example:
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;
}
}
}
Used like this:
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);
it will output
User.Name: Foo
User.Number: 19
User.Address.Street: MyStreet
User.Address.State: MyState
User.Address.Country: SomeCountry
First of all, avoid using reflection unless you really need it. It's slow, it's messy, it's borderline undebuggable (and I love it, but that's another thing)
If you want to dump the whole content of your object, I would recommend to transfer that to the objects themselves, they should know their inner state. You could use the objects ToString
method to write their inner state, or you could define an interface for displaying the inner state
interface IStateDisplay
{
string GetInnerState();
}
and make your objects implement it. Then the code for displaying the properties will be
Console.WriteLine(user.GetInnerState());
Another option would be to use a tool like AutoMapper that hides the complexities and intricacies of reflection from you, and exposes a nice API to use.
However, if you are learning about reflection, printing the state of a complex object is a nice exercise. A few pointers in that direction:
public string Name;
is not a property, it's a field, so type.GetProperties()
will not return it. Read up on what C# properties are, and how they are used and defined. A minimal property declaration is
public string Name {get; set;}
Also, prp.GetType()
will return the type information for the PropertyInfo
type, not for the type of the property it contains. What you need in this case is the prp.PropertyType
property.
Next, I don't think the Type.IsPrimitive
check is what you want it to be. That property returns true for the Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single types, and false for everything else. Most importantly typeof(string).IsPrimitive
returns false.
On the same note, I don't think the Type.IsClass
check is what you want it to be, either. As you are using it, that only check if the property is of a value or of a reference type, and as value types (struct
) can be also very complex and contain properties and fields of their own, the check does not make sense.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With