我正在尝试重用现有代码......但没有成功。以下是代码段:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Reflection;
namespace GenApp.Utils.Reflection
{
class FieldTraverser
{
public static string SearchFieldValue(object obj, int MaxLevel, string strFieldMeta , ref object fieldValue)
{
if (obj == null)
return null;
else
{
StringBuilder sb = new StringBuilder();
bool flagShouldStop = false;
FieldTraverser.PrivDump(sb, obj, "[ObjectToDump]", 0, MaxLevel , ref flagShouldStop , ref fieldValue);
return sb.ToString();
}
} //eof method
public static object GetFieldValue(object obj, string fieldName, ref bool flagShouldStop, ref object objFieldValue)
{
FieldInfo fi;
Type t;
t = obj.GetType();
fi = t.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
if (fi == null)
return null;
else
{
if (fi.Name.Equals(fieldName))
{
objFieldValue = fi.GetValue(obj);
flagShouldStop = true;
}
return fi.GetValue(obj);
} //eof else
} //eof method
protected static void DumpType(string InitialStr, StringBuilder sb, object obj,
int level, System.Type t, int maxlevel , ref bool flagShouldStop , ref object objFieldValue
)
{
FieldInfo[] fi;
fi = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
if (t == typeof(System.Delegate)) return;
foreach (FieldInfo f in fi)
{
PrivDump(sb, f.GetValue(obj), f.Name, level + 1, maxlevel , ref flagShouldStop , ref objFieldValue);
if (flagShouldStop == true)
return;
}
object[] arl;
int i;
if (obj is System.Array)
{
try
{
arl = (object[])obj;
for (i = 0; i < arl.GetLength(0); i++)
{
PrivDump(sb, arl[i], "[" + i + "]", level + 1, maxlevel, ref flagShouldStop, ref objFieldValue);
if (flagShouldStop == true)
return;
}
}
catch (Exception) { }
}
}
protected static void PrivDump(StringBuilder sb, object obj, string objName, int level, int MaxLevel, ref bool flagShouldStop, ref object objFieldValue)
{
if (obj == null)
return;
if (MaxLevel >= 0 && level >= MaxLevel)
return;
string padstr;
padstr = "";
for (int i = 0; i < level; i++)
if (i < level - 1)
padstr += "|";
else
padstr += "+";
string str;
string[] strarr;
Type t;
t = obj.GetType();
strarr = new String[7];
strarr[0] = padstr;
strarr[1] = objName;
strarr[2] = " AS ";
strarr[3] = t.FullName;
strarr[4] = " = ";
strarr[5] = obj.ToString();
strarr[6] = "\r\n";
sb.Append(String.Concat(strarr));
if (obj.GetType().BaseType == typeof(ValueType))
return;
FieldTraverser.DumpType(padstr, sb, obj, level, t, MaxLevel, ref flagShouldStop , ref objFieldValue);
Type bt;
bt = t.BaseType;
if (bt != null)
{
while (!(bt == typeof(Object)))
{
str = bt.FullName;
sb.Append(padstr + "(" + str + ")\r\n");
FieldTraverser.DumpType(padstr, sb, obj, level, bt, MaxLevel , ref flagShouldStop , ref objFieldValue);
bt = bt.BaseType;
if (bt != null)
continue;
break;
} while (bt != typeof(Object)) ;
}
} //eof method
}//eof class
} //eof namespace
答案 0 :(得分:3)
请注意,您很少需要弄乱FieldInfo
;字段很少公开,您通常应该使用PropertyInfo
s(GetProperties()
)。但是,GetFields
会起作用。对于公共字段,只需GetFields()
;对于私人领域,您也需要BindingFlags
:
class Foo {
public string abc;
}
class Bar : Foo {
private int def;
}
static class Program {
static void Main() {
object obj = new Bar();
FieldInfo[] fields = obj.GetType().GetFields(
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
foreach(FieldInfo field in fields) {
Console.WriteLine(field.Name + " = " + field.GetValue(obj));
}
}
}
答案 1 :(得分:1)
答案 2 :(得分:1)
您是否尝试过指定BindingFlags.FlattenHierarchy
?
答案 3 :(得分:0)
感谢我的答案,我试图做这样的事情(我仍然不确定.ToString()是比较字段值的最佳方式:
using System;
using System.Reflection;
class Foo
{
public string abc;
}
class Bar : Foo
{
private int def = 0;
}
static class Program
{
static void Main()
{
object obj = new Bar();
object objShouldNotHaveIt = new Foo();
object objShouldHaveIt = new Bar();
string myQuestion = "How-to get a System.Collections.Generic.List<FieldInfo> list which holds all FieldInfo’s of an object of a Type T up to the Object in the class hierarchy in C# ?";
if (Program.SearchFieldByValue(objShouldNotHaveIt, "def", 0))
Console.WriteLine(" NOK");
if ( Program.SearchFieldByValue(objShouldHaveIt , "def" , 0 ))
Console.WriteLine(" OK ");
Console.WriteLine("Is a " + myQuestion.Length.ToString() + " chars long string considered as long question ? ");
Console.ReadLine();
} //eof main
public static bool SearchFieldByValue ( object obj , string strFieldName , object objFieldValue )
{
FieldInfo[] fields = obj.GetType().GetFields(
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
foreach (FieldInfo field in fields)
{
object objFieldValueReflected = field.GetValue(obj) ;
Console.WriteLine(field.Name + " = " + field.GetValue(obj));
if (objFieldValueReflected != null && objFieldValue.ToString().Equals(objFieldValueReflected.ToString()))
return true;
else
continue;
}
return false;
} //eof method
} //eof class