c# - Iterate properties and nested first level properties -
i have following classes
public class car { public int carid { get; set;} public string description { get; set;} public engine engine { get; set;} } public class engine { public int engineid { get; set;} public int description { get; set;} }
now want iterate properties in car , properties in engine, dont want hardcode property names "car or engine"
example properties of car, obj
instance of car.
var properties = obj.gettype().getproperties(bindingflags.flattenhierarchy | bindingflags.instance | bindingflags.public);
but doesnt iterate properties of engine.
flattenhierarchy
not think does, , instead follows inheritance hiearchy static members.
if you'd sub-properties objects, you'll need yourself:
static ienumerable<propertyinfo> flattenproperties(type type) { // assumption #1: not want "simple" types enumerated if (!type.isclass) return enumerable.empty<propertyinfo>(); // assumption #2: want ignore "the usual suspects" if (type.namespace != null && type.namespace.startswith("system")) return enumerable.empty<propertyinfo>(); // assumption #3: class hierarchy won't destroy recursion // assumption #4: want propertyinfo return type.getproperties(bindingflags.flattenhierarchy | bindingflags.instance | bindingflags.public) .selectmany(pi => new[] { pi } .concat(flattenproperties(pi.propertytype))); }
if used in code (a) know depth of recursion, , (b) have means alter code, i'd suggest creating either base class, interface, or attribute these types/properties.
// replace assumptions #1 , #2 above this: // assumption #5: given interface isomething { } if (!typeof(isomething).isassignablefrom(type)) return enumerable.empty<propertyinfo>();
if need "property tree" (i.e. assumption #4 incorrect):
static ienumerable<ienumerable<propertyinfo>> flattenproperties( type type, ienumerable<propertyinfo> ancestors = null) { // change assumptions #1/#2 or #5 yield break // ... ancestors = ancestors ?? enumerable.empty<propertyinfo>(); var properties = type.getproperties( bindingflags.flattenhierarchy | bindingflags.instance | bindingflags.public); foreach (var property in properties) { // again, assumption #3: class hierarchy won't destroy recursion // assumption #6: want initial nested property yield return ancestors.concat(new[] { property }); foreach (var nested in flattenproperties( property.propertytype, ancestors.concat(new [] { property }))) { yield return nested; } } }
which, in second case, produces output similar to:
// foreach (var tree in flattenproperties(typeof(car))) // { // console.writeline("{0}", string.join(".", tree.select(pi => pi.name))); // } carid description engine engine.engineid engine.description
Comments
Post a Comment