как получить весь примитивный тип объекта

Я хочу иметь все свойства объекта, который имеет примитивный тип, и если объект имеет отношение к другому classу, я хочу иметь примитивные свойства этого другого classа

проблема в том, что если объект A имеет объект B и B имеет A, что я могу сделать

в простом случае с помощью отражения я могу получить примитивные свойства первого уровня, но я не могу войти в объект B и снова получить примитивные свойства A ,, будет создан цикл, что предлагает ur?

public class A { public string Name{get;set;} public BB{get;set;} } public class B { public string Category{get;set;} public AA{get;set;} } 

Вы можете отслеживать посещаемые типы, чтобы избежать рекурсии:

 public class A { public string Name { get; set; } public BB { get; set; } } public class B { public string Category { get; set; } public AA { get; set; } } class Program { static void Main() { var result = Visit(typeof(A)); foreach (var item in result) { Console.WriteLine(item.Name); } } public static IEnumerable Visit(Type t) { var visitedTypes = new HashSet(); var result = new List(); InternalVisit(t, visitedTypes, result); return result; } private void InternalVisit(Type t, HashSet visitedTypes, IList result) { if (visitedTypes.Contains(t)) { return; } if (!IsPrimitive(t)) { visitedTypes.Add(t); foreach (var property in t.GetProperties()) { if (IsPrimitive(property.PropertyType)) { result.Add(property); } InternalVisit(property.PropertyType, visitedTypes, result); } } } private static bool IsPrimitive(Type t) { // TODO: put any type here that you consider as primitive as I didn't // quite understand what your definition of primitive type is return new[] { typeof(string), typeof(char), typeof(byte), typeof(sbyte), typeof(ushort), typeof(short), typeof(uint), typeof(int), typeof(ulong), typeof(long), typeof(float), typeof(double), typeof(decimal), typeof(DateTime), }.Contains(t); } } с public class A { public string Name { get; set; } public BB { get; set; } } public class B { public string Category { get; set; } public AA { get; set; } } class Program { static void Main() { var result = Visit(typeof(A)); foreach (var item in result) { Console.WriteLine(item.Name); } } public static IEnumerable Visit(Type t) { var visitedTypes = new HashSet(); var result = new List(); InternalVisit(t, visitedTypes, result); return result; } private void InternalVisit(Type t, HashSet visitedTypes, IList result) { if (visitedTypes.Contains(t)) { return; } if (!IsPrimitive(t)) { visitedTypes.Add(t); foreach (var property in t.GetProperties()) { if (IsPrimitive(property.PropertyType)) { result.Add(property); } InternalVisit(property.PropertyType, visitedTypes, result); } } } private static bool IsPrimitive(Type t) { // TODO: put any type here that you consider as primitive as I didn't // quite understand what your definition of primitive type is return new[] { typeof(string), typeof(char), typeof(byte), typeof(sbyte), typeof(ushort), typeof(short), typeof(uint), typeof(int), typeof(ulong), typeof(long), typeof(float), typeof(double), typeof(decimal), typeof(DateTime), }.Contains(t); } } 

Мне скучно на работе, ожидая сборки, получайте удовольствие от вашей домашней работы;)

 namespace Scratchpad { public static class TypeExtractor { public static IEnumerable ExtractTypes(this Type owner, HashSet visited = null) { if (visited == null) visited = new HashSet(); if (visited.Contains(owner)) return new Type[0]; visited.Add(owner); switch (Type.GetTypeCode(owner)) { case TypeCode.Object: break; case TypeCode.Empty: return new Type[0]; default: return new[] {owner}; } return owner.GetMembers(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy) .SelectMany(x => x.ExtractTypes(visited)).Union(new[] {owner}).Distinct(); } public static IEnumerable ExtractTypes(this MemberInfo member, HashSet visited) { switch (member.MemberType) { case MemberTypes.Property: return ((PropertyInfo) member).PropertyType.ExtractTypes(visited); break; case MemberTypes.Field: return ((FieldInfo) member).FieldType.ExtractTypes(visited); default: return new Type[0]; } } } public class A { public string Name { get; set; } public BB { get; set; } } public class B { public string Category { get; set; } public AA { get; set; } } internal class Program { private static void Main(string[] args) { var q = typeof (A).ExtractTypes(); foreach (var type in q) { Console.Out.WriteLine(type.Name); } } } } 

Я бы сделал следующее:

  void Traverse(Type type, ISet marks, ICollection result) { if (marks.Contains(type)) return; else marks.Add(type); foreach (var propertyInfo in type.GetProperties()) if (propertyInfo.PropertyType.IsPrimitive) result.Add(propertyInfo); else Traverse(propertyInfo.PropertyType, marks, result); } 

а также

 var props = new List(); Traverse(yourRootType, new HashSet(), props); 

Вам нужно отслеживать типы, которые вы уже проверили.

 public static List ProcessType(Type type) { return ProcessType(type, new List()); } public static List ProcessType(Type type, List processedTypes) { // Keep track of results var result = new List(); // Iterate properties of the type foreach (var property in type.GetProperties()) { var propertyType = property.PropertyType; // If the property has a primitive type if (propertyType.IsPrimitive) { // add it to the results result.Add(property); } // If the property has a non-primitive type // and it has not been processed yet else if (!processedTypes.Contains(propertyType)) { // Mark the property's type as already processed processedTypes.Add(propertyType); // Recursively processproperties of the property's type result.AddRange(ProcessType(propertyType, processedTypes)); } } return result; }