いくつかのクラスがあります:
public class A
{
public int Id { get; set; }
public B BValue { get; set; }
public A()
{
this.Id = 1000;
this.BValue = new B();
}
}
public class B
{
public string Name { get; set; }
public C CValue { get; set; }
[NoLog]
public string Secret { get; set; }
public B()
{
this.Name = "Empty Name";
this.CValue = new C();
}
}
public class C
{
public string Description { get; set; }
public C()
{
this.Description = "Empty Description";
}
}
および NoLog カスタム属性:
public class NoLogAttribute : Attribute
{
}
あなたの質問によると、次のように sth を使用してきれいに印刷します。
public static void PrintProperties(object obj, int indent = 4, char intendCharacter = ' ')
{
if (obj == null) return;
string indentString = new string(intendCharacter, indent);
Type objType = obj.GetType();
foreach (var pName in GetPropertiesToLogWithCaching(obj))
{
var property = objType.GetProperty(pName);
object propValue = property.GetValue(obj, null);
if (property.PropertyType.Assembly == objType.Assembly)
{
Console.WriteLine("{0}{1}:", indentString, property.Name);
PrintProperties(propValue, indent + 2);
}
else
{
Console.WriteLine("{0}{1}: {2}", indentString, property.Name, propValue);
}
}
}
プロパティに (名前で) アクセスする方法を変更し、この 2 つのメソッドを追加しました。
public static List<string> GetPropertiesToLogWithCaching(object obj)
{
List<string> propertiesToLog = new List<string>();
if (obj != null)
{
string key = obj.GetType().FullName;
propertiesToLog = CacheLayer.Get<List<string>>(key);
if (propertiesToLog == null)
{
propertiesToLog = GetPropertiesToLog(obj);
CacheLayer.Add<List<string>>(propertiesToLog, key);
}
}
return propertiesToLog;
}
public static List<string> GetPropertiesToLog(object obj)
{
List<string> propertiesToLog = new List<string>();
if (obj != null)
{
foreach (var p in obj.GetType().GetProperties().Where(prop => !Attribute.IsDefined(prop, typeof(NoLogAttribute))))
{
propertiesToLog.Add(p.Name);
}
}
return propertiesToLog;
}
ここで、GetPropertiesToLogWithCaching は GetPropertiesToLog のラッパーです。ここで見つけることができる ChacheLayer オブジェクトhttp://www.deanhume.com/home/blogpost/object-caching----net-4/37
今は再帰的で、キャッシュがあります。回答の最初のバージョンで書いたように。アイデアは、プロパティ名のリストをキャッシュし、属性をテストせずに名前で GetProperty することです。キャッシュのキーとして、obj タイプの FullName を使用できます。次に、それがどのように機能するかを確認する必要があります。