我有如下属性集:
public string Foo1 {set;get;}
public string Foo2 {set;get;}
public string Foo3 {set;get;}
public string Foo4 {set;get;}
public string Foo5 {set;get;}
public string Foo6 {set;get;}
public string Foo7 {set;get;}
public string Foo8 {set;get;}
public string Foo9 {set;get;}
......
public string Foo50 {set;get;}
然后我按如下方式遍历集合:
foreach(var element in sortedCollection.Keys){
if(element != null)
// in this block I would like to assign the element to the properties above
// ex:
foo?? = sortedCollection[element];
// ?? need to be replaced by index.
}
有一种简单的方法吗?
答案 0 :(得分:5)
我认为更好的设计是:
public List<string> Foos { get; private set; }
如果你无法改变它,你可能会做类似的事情:
var type = typeof(MyCalss);
int index = 1;
foreach (var key in sortedCollection.Keys)
{
var value = sortedCollection[key];
var prop = type.GetProperty("Foo" + index);
if (prop != null) prop.SetValue(this, value, null);
index++;
}
...当然有一些错误处理,this
假设这是你班级中的方法。您能否根据sortedCollection
?
答案 1 :(得分:2)
你可以使用反射并在循环中执行:
for ( int i = 1 ; i < 51 ; i++)
this.GetType().GetProperty(string.Format("Foo{0}",i)).SetValue(this,desiredValue,null);
但我想我会推荐使用索引器
http://msdn.microsoft.com/en-us/library/2549tw02%28v=vs.80%29.aspx
答案 2 :(得分:1)
你可以做你想做的事:
但为什么不用List<string> Foos
代替很多属性?
答案 3 :(得分:1)
你应该使用反射。
this.GetType()。GetProperty(“Foo”+ i)。SetValue(this,sortedCollection [element],null);
但有两件事:
答案 4 :(得分:1)
您需要使用反射(Type.GetProperty())来获取属性并设置它的值。
假设属性在名为MyClass的类中定义:
foreach(var element in sortedCollection.Keys){
if(element != null)
// in this block I would like to assign the element to the properties above
// ex:
//foo?? = sortedCollection[element];
// not sure how you are getting the index here, may be you need to use for loop
PropertyInfo pi = typeof(MyClass).GetProperty("Foo" + index);
// ?? need to be replaced by index.
if (pi != null)
{
pi.SetValue(<object of MyClass>, sortedCollection[element], null);
}
}
答案 5 :(得分:1)
void Main()
{
var foo = new Foo();
foo[1] = "Foo1";
//foo.Dump();
}
public class Foo
{
public string Foo1 {set;get;}
public string Foo2 {set;get;}
public string Foo3 {set;get;}
public string Foo4 {set;get;}
public string Foo5 {set;get;}
public string Foo6 {set;get;}
public string Foo7 {set;get;}
public string Foo8 {set;get;}
public string Foo9 {set;get;}
public string this[int index]
{
get
{
return getPropertyValue(index);
}
set
{
setPropertyValue(index, value);
}
}
private void setPropertyValue(int i, string value)
{
var propi = this.GetType().GetProperty("Foo" + i);
if (propi != null)
propi.SetValue(this,value,null);
}
private string getPropertyValue(int i)
{
var propi = this.GetType().GetProperty("Foo" + i);
if (propi != null)
return (string)propi.GetValue(this, null);
return null;
}
}
答案 6 :(得分:1)
我实际上会使用反射,或者如果调用它很多,请创建一个动态方法并且ILEmit执行它(在运行时比反射快得多)。
然而,只是为了提出不同的建议,您可以更改包含Foo *属性的类,以便从索引列表中读取每个getter / setter:
public class FooOfDoom
{
public string[] Foos = new string[2];
public string Foo1
{
set { Foos[0] = value; }
get { return Foos[0]; }
}
public string Foo2
{
set { Foos[1] = value; }
get { return Foos[1]; }
}
}
然后你的类并没有真正改变,因为它与所有其他代码的合同,因为属性仍然存在,但现在你可以分配到Foos
而不是通过每个单独的属性。< / p>
同样,实际上如果我自己做的话,我实际上会使用DynamicMethod。
答案 7 :(得分:1)
就个人而言,我不同意这里的大多数其他海报。我认为反射的使用应限于那些真正需要它的情况(对象检查,某些GUI情况等)。在这种情况下,只需更多一点打字,就可以编写一个强类型的程序,仍然可以做你想要的。我会提供两种选择。两种选择都可以按名称和索引访问您的媒体资源。
在第一种选择中,我假设我们可以更改属性的定义。在第二种选择中,我将假设这些定义必须保持不变。
第一种方法是将数据移动到一个单独的数组中,添加辅助方法以通过索引访问数据,并改变属性以使用辅助方法:
private class Version1 {
private readonly string[] underlyingData=new string[50];
public string Foo1 { get { return ReadFoo(1); } set { SetFoo(1, value); } }
public string Foo2 { get { return ReadFoo(2); } set { SetFoo(2, value); } }
public string Foo3 { get { return ReadFoo(3); } set { SetFoo(3, value); } }
//......
public string Foo50 { get { return ReadFoo(50); } set { SetFoo(50, value); } }
private string ReadFoo(int index) {
return underlyingData[index-1]; //1-based indexing
}
private void SetFoo(int index, string value) {
underlyingData[index-1]=value; //1-based indexing
}
}
第二种方法是保持属性定义不变,两个静态的委托数组表示这些属性的读写功能。
private class Version2 {
private static readonly Func<Version2, string>[] readers=new Func<Version2, string>[] {
c => c.Foo1,
c => c.Foo2,
c => c.Foo3,
//......
c => c.Foo50,
};
private static readonly Action<Version2, string>[] writers=new Action<Version2, string>[] {
(c,v) => c.Foo1=v,
(c,v) => c.Foo2=v,
(c,v) => c.Foo3=v,
//......
(c,v) => c.Foo50=v,
};
public string Foo1 { set; get; }
public string Foo2 { set; get; }
public string Foo3 { set; get; }
//......
public string Foo50 { set; get; }
private string ReadFoo(int index) {
return readers[index-1](this); //1-based indexing
}
private void SetFoo(int index, string value) {
writers[index-1](this, value); //1-based indexing
}
}