.NET 4.5 C#列表和它們的值
爲了支持「導出到Excel」功能很多類,我需要能夠採取一個類,然後從它那裏得到公衆的列表屬性名稱(用於標題)和屬性值(用於行)
有沒有辦法反映一個類的實例並獲取屬性名稱和屬性值?
.NET 4.5 C#列表和它們的值
爲了支持「導出到Excel」功能很多類,我需要能夠採取一個類,然後從它那裏得到公衆的列表屬性名稱(用於標題)和屬性值(用於行)
有沒有辦法反映一個類的實例並獲取屬性名稱和屬性值?
下面是如何做到這一點的快速示例。當然,您需要更新它,以便正確創建/構建CSV,但這會讓您瞭解如何獲取所需的值。
class Program
{
static void Main(string[] args)
{
var myClass = new MyClass()
{
Number = 1,
String = "test"
};
var properties = myClass.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var property in properties)
{
var columnName = property.Name;
var value = myClass.GetType().GetProperty(columnName).GetValue(myClass, null);
Console.WriteLine(string.Format("{0} - {1}", columnName, value));
}
Console.ReadKey();
}
}
public class MyClass
{
public int Number { get; set; }
public string String { get; set; }
}
你可以使用一些像這樣:
public static Dictionary<string, object> KeyValue(object obj)
{
return obj.GetType().GetProperties().ToDictionary(
m => m.Name,
m => m.GetValue(obj, new object[] { })
);
}
其實我最近創建這樣的事情對我的工作。我正在編寫一個自定義CSV序列化程序類以支持構思不良的CSV文件規範。
public CSVSerializer Serialize<T>(T data, Func<T, object> map)
{
if (map == null) throw new ArgumentNullException("map");
object mappedData = map(data);
if (mappedData == null) throw new NullReferenceException("Mapped data produced null value");
// Iterate over public members of `mappedData`
MemberInfo[] members = mappedData.GetType().GetMembers(BindingFlags.Instance | BindingFlags.Public);
List<string> values = new List<string>();
foreach (MemberInfo member in members)
{
// Skip events and methods
if (!(member is FieldInfo || member is PropertyInfo)) continue;
// Value of `mappedData`
object memberVal = MemberInfoValue(member, mappedData);
if (memberVal == null)
{
// If the actual value stored by `memberVal` is null, store string.Empty and continue
values.Add(string.Empty);
continue;
}
// Check if `memberVal` contains a member named "map"
MemberInfo[] maps = memberVal.GetType().GetMember("map");
MemberInfo memberMap = maps.Length > 0 ? maps[0] : null;
string val = MapToString(memberVal, o => o.ToString());
if (map != null) // map is present
{
// Get first property other than map
MemberInfo dataVal = memberVal.GetType().GetMembers(BindingFlags.Instance | BindingFlags.Public)
.Where(mi => mi is FieldInfo || mi is PropertyInfo)
.Except(new MemberInfo[] { memberMap })
.DefaultIfEmpty(memberMap)
.FirstOrDefault();
object tmp = MemberInfoValue(memberMap, memberVal);
if (dataVal == memberMap)
{
// map is only property, so serialize it
val = MapToString(tmp, o => o.ToString());
}
else
{
// try to serialize map(dataVal), or use empty string if it fails
Delegate dlg = tmp as Delegate;
if (dlg != null)
{
object param = MemberInfoValue(dataVal, memberVal);
try { val = MapToString(dlg, d => d.DynamicInvoke(param).ToString()); }
catch (Exception ex)
{
// exception should only occur with parameter count/type mismatch
throw new SerializationException(string.Format("Poorly formatted map function in {0}", member.Name), ex);
}
}
else
{
// map is not a delegate (!!)
throw new SerializationException(string.Format("map member in {0} is not a delegate type", member.Name));
}
}
}
// Handle quotes and the separator string
val = val.Trim('"');
if (val.Contains("\""))
{
val = val.Replace("\"", "\\\"");
}
if (val.Contains(Separator))
{
val = string.Format("\"{0}\"", val);
}
values.Add(val);
}
string line = string.Join(Separator, values);
Writer.WriteLine(line);
return this;
}
此功能串行化他們定義的順序公共領域和data
性能;這些成員的名字被忽略。
如果您只對屬性感興趣,您可以使用GetProperties
而不是GetMembers
(使用PropertyInfo
而不是MemberInfo
)。如果您沒有創建CSV,那麼您顯然可以忽略CSV文件格式部分。
MemberInfoValue(info, parent)
返回((FieldInfo)info).GetValue(parent)
或((PropertyInfo)info).GetValue(parent, null)
,視情況而定。 MapToString
只是一個空防護功能。
map
參數的存在和尋找名爲「map」的成員是我特殊情況的必需品之一,儘管它對您有用。該映射允許的東西,如:
mySerializer.Serialize(myPersonObject,
p => new {
name = string.Format("{0}, {1}", p.LastName, p.FirstName),
address = p.address
});
我有Serialize
過載它調用Serialize(data, d => d);
。狩獵「地圖」成員允許的東西,如:
mySerializer.Serialize(new {
employeeID = new { val = myEmployeeObject.ID, map = d => d.ToUpperCase() },
employeeName = myEmployeeObject.Name
});