动态对象引用 C#



我创建了一个方法Mydata来从列表中分配新数据(listData(。但是我这样做的方式不是动态的,我正在使用 if else 语句来确定要添加多少数据以及它属于哪个属性。有没有办法简化它或动态地使用它,而不使用 if else 语句。

public List<Data> _newData = new List<Data>();
public void Mydata(int number, List<string> listData) {
             if (number == 1) {
              _newData.Add(new Data() {
                       variable0 = listData[0].ToString(),
                 });
             } 
             else if (number == 2) {
             _newData.Add(new Data() {
                       variable0 = listData[0].ToString(),
                       variable1 = listData[1].ToString(),
                 });    
               }
             else if (number == 3) {
             _newData.Add(new Data() {
                       variable0 = listData[0].ToString(),
                       variable1 = listData[1].ToString(),
                       variable2 = listData[2].ToString(),
                 });    
               } 

class Data
{
  public string variable1 { get; set; }
  public string variable2 { get; set; }
  public string variable3 { get; set; }
  public string variable4 { get; set; }
  ..
  public string variable10 { get; set; }
}

假设你想保持数据结构的原样(不推荐 - 请参阅注释(,明显的代码简化将是:

var d = new Data
{
    variable0 = listData[0];
};
if (number >= 1) d.variable1 = listData[1];
if (number >= 2) d.variable2 = listData[2];
if (number >= 3) d.variable3 = listData[3];
_newData.Add(d);

正确的解决方案是Data应使用string[]List<string>而不是单独的属性。但是,可以通过几种方式模拟它。

由于 C# 没有成员引用,因此可以使用委托来设置属性:

public void Mydata(int number, List<string> listData) {
    var nd = new Data();
    var setters = new Action<Data,string>[] {
        (d,s) => d.variable0 = s,
        (d,s) => d.variable1 = s,
        (d,s) => d.variable2 = s,
        (d,s) => d.variable3 = s,
        (d,s) => d.variable4 = s,
        (d,s) => d.variable5 = s,
        (d,s) => d.variable6 = s,
        (d,s) => d.variable7 = s,
        (d,s) => d.variable8 = s,
        (d,s) => d.variable9 = s,
        (d,s) => d.variable10 = s,
    };
    while (number-- > 0)
        setters[number](nd, listData[number]);
    _newData.Add(nd);
}

或者,您可以更改Data以支持返回对字段的引用的索引属性,尽管这确实会给每个Data1对象增加大量开销:

public class Data1 {
    public string variable0;
    public string variable1;
    public string variable2;
    public string variable3;
    public string variable4;
    public string variable5;
    public string variable6;
    public string variable7;
    public string variable8;
    public string variable9;
    public string variable10;
    public delegate ref string RefStringFunc();
    private List<RefStringFunc> refvar;
    public Data1() {
        refvar = new List<RefStringFunc>() {
            () => ref variable0,
            () => ref variable1,
            () => ref variable2,
            () => ref variable3,
            () => ref variable4,
            () => ref variable5,
            () => ref variable6,
            () => ref variable7,
            () => ref variable8,
            () => ref variable9,
            () => ref variable10,
        };
    }
    public ref string this[int index]
    {
        get
        {
            return ref refvar[index]();
        }
    }
}

然后,可以使用索引属性分配值:

public void Mydata1(int number, List<string> listData) {
    var nd = new Data1();
    while (number-- > 0)
        nd[number] = listData[number];
    _newData.Add(nd);
}

最后,您可以使用反射,但这实际上不是表达意图的最佳方式,也不推荐使用(尽管它确实提供了另一种模拟成员引用的方法(。

最新更新