[英]C# Reflection - Populate class properties from delimited strings using reflection
我正在嘗試使用從不規則 CSV 格式文件中檢索到的數據填充一個類。 我能夠從文件中獲取數據,確定文件中是否存在屬性值,並從檢索到的數據創建對象。
在嘗試填充類屬性時,我嘗試過:
this.GetType().GetProperty(propName).SetValue(this, newProp);
...導致異常:
System.ArgumentException: 'System.Collections.Generic.List
1[System.Collections.Generic.List
1[SharpCodingTestApp.Bar]]'類型的對象無法轉換為類型'System.Collections.Generic.List`1[SharpCodingTestApp] 。酒吧]'。'
和...
this.GetType().InvokeMember(propName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty, Type.DefaultBinder, this, new object[] { newProp });
...導致異常:
System.MissingMethodException: '找不到方法'SharpCodingTestApp.Bar'。'
這是我目前正在運行的代碼:
public class FooBar
{
private string _configFile;
public Foo PropFoo { get; get; }
public List<Bar> PropBar { get; set; }
public void Load()
{
List<object> props = new List<object>();
if (String.IsNullOrWhiteSpace(_configFile) != true)
{
//Does the config file contain all of the required settings?
if (ConfigFileContainsRoomConfigSettings(_configFile))
{
//Get the information we need from the file.
string[] configLines = GetConfigLines(_configFile);
foreach (var line in configLines)
{
var propName = line.Split(", ")[0].Trim(' ');
var newProp = CreatePropertyObejct(propName, line);
this.GetType().InvokeMember(propName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty, Type.DefaultBinder, this, new object[] { newProp });
}
}
}
}
private object CreatePropertyObejct(string paramPropertyName, string paramPropertyConfigString)
{
var prop = this.GetType().GetProperty(paramPropertyName);
if (prop.PropertyType.Name.ToLower().Contains("list") == true)
{
var listType = typeof(List<>);
var constructedListType = listType.MakeGenericType(prop.PropertyType);
return Activator.CreateInstance(constructedListType);
}
else
{
return Activator.CreateInstance(prop.PropertyType, paramPropertyConfigString, ',');
}
}
}
這是文件中數據的示例:
Foo, FooVal1, FooVal2
Bar, BarVal1, BarVal2, BarVal3, BarVal4
Bar, BarVal1, BarVal2, BarVal3, BarVal4
每個分隔字符串中的第一個值包含數據所屬的屬性名稱。
Bar 在文件中有多個條目來表示列表中的每個對象。
我如何解決異常,是否有更好的方法來做我想做的事情?
謝謝。
如果您正在編寫反射代碼,請不要使用字符串比較。 並嘗試預先構建和緩存您需要的一切。 但是,如果您不知道要問什么問題,則很難找到正確的方法。
你的第一個錯誤發生了,因為prop.PropertyType
已經是一個List<T>
,所以typeof(List<>).MakeGenericType(prop.PropertyType)
,正在定義一個List<List<T>>
。
輸入數據實際上是 csv 嗎? 數據可以包含引號、逗號和換行符嗎? 然后.Split(", ")
不會削減它。 您需要找到/實現一個合適的 c# 解析器。
我不太清楚您要對其他每個 csv 列做什么?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.