我有一个在循环的每次迭代开始时实例化的类。在循环内部,需要使用存储过程返回的表的行值填充它的属性。因为我必须遍历每一行的每一列,以便知道需要为该类的哪个属性赋值,何时,我有一个字典将列名映射到索引。此索引引用列表中的位置,该位置存储类的实例的属性:
while (reader.Read() && reader.HasRows)
{
Subscription subscription = new Subscription();
List<string> subscrData = new List<string>
{
subscription.attr1,
subscription.attr2,
subscription.attr3,
subscription.attr4
}
Dictionary<string, int> columnDict = new Dictionary<string, int>
{
{"attr1": 0},
{"attr2":1},
{"attr3":2},
{"attr4":3}
}
foreach (string colName in columnDict.Keys)
{
if (reader.GetSchemaTable().Columns[colName] == null)
subscrData[columnDict[colName]] = "null";
else
{
subscrData[columnDict[colName]] = reader[colName].ToString();
nullsReturned = false;
}
}
我可能从更多的C ++方法来实现这一点,因为您可以存储对类实例的引用并修改其属性,但这并不适用于C#,因为列表存储了值。
如何重构此代码,以便我可以修改类实例的实际属性,同时仍能检查从存储过程返回的每列是否为空?
答案 0 :(得分:1)
您不需要此案例的列表。你想要在你的类中添加一个像setAttribute(string attributeName)这样的方法(并在其中构建一个switch / case来修改给定的属性);或者,使用反射来更改给定名称的实例字段。
答案 1 :(得分:1)
我同意哈桑的观点。但仅仅是为了您的信息:要实现您的方法,您可以使用Lambda表达式来跟踪对属性的引用(=属性)。
这样的事情会起作用:
Subscription subscription = new Subscription();
List<Expression<Func<Subscription, string>>> subscrData = new List<Expression<Func<Subscription, string>>>
{
a => a.attr1,
a => a.attr2,
a => a.attr3,
a => a.attr4,
};
//E.g. To update attribute 3 you can do this:
var prop = (PropertyInfo)((MemberExpression)subscrData[2].Body).Member;
prop.SetValue(subscription, "test string", null);