使用匿名功能自动初始化属性

时间:2019-05-31 00:34:38

标签: c# initialization automatic-properties

我正在尝试摆脱一些带有匿名函数和类的代码。

我坚持下去:

public List<Object> Years { get; set; } = GetYears();

private static List<Object> GetYears()
{
    List<Object> retList = new List<Object>();

    retList.Add(new { Value = (byte)255, Name = "Any" });
    retList.Add(new { Value = (byte)254, Name = "None" });

    for (byte i = 0; i < 50; i++)
    {
        retList.Add(new { Value = i, Name = (2000 + i).ToString() });
    }
    return retList;
}

是否可以摆脱静态的GetYears()方法?

我的意思是这样的:

public List<Object> Years { get; set; } = () =>  
{
    List<Object> retList = new List<Object>();
    for (byte i = 0; i < 50; i++)
    {
        retList.Add(new { Value = i, Name = (2000 + i).ToString() });
    }
    return retList;
}

问题在于字段初始化程序无法引用非静态方法。

可以解决这个问题吗?

编辑:我添加了以下两行代码:

retList.Add(new { Value = (byte)255, Name = "None" });
retList.Add(new { Value = (byte)254, Name = "Any" });

2 个答案:

答案 0 :(得分:3)

从技术上讲,您可以执行以下操作

public class LambdaInitalization {
    public List<Object> Years = ((Func<List<Object>>)(() =>  
    {
        List<Object> retList = new List<Object>();
        for (byte i = 0; i < 50; i++)
        {
            retList.Add(new { Value = i, Name = (2000 + i).ToString() });
        }
        return retList;
    }))();
}

这将创建一个匿名函数,该函数返回一个List<Object>,然后运行它(不幸的是,不能隐含它,它必须是显式强制转换)。

更好的解决方案是只使用构造函数,几乎完全可以完成构造函数的作用。

public class CtorInitalization {
    public List<Object> Years { get; set; }

    public CtorInitalization() {
        Years = new List<Object>();
        for (byte i = 0; i < 50; i++)
        {
            Years.Add(new { Value = i, Name = (2000 + i).ToString() });
        }
    }
}

有趣的是,lamda初始化无论如何都会编译到构造函数 中,因此从功能上讲,在构造函数之外定义它没有有效的用途。

在此处查看这两种方法:https://dotnetfiddle.net/1f62Hj

答案 1 :(得分:2)

如前所述,您无法通过设计做到这一点,初始化器无法引用非静态字段方法属性'字段,而且不是一个匿名方法。

您可以将其放入构造函数中,其他选择是将其设置为Lazy<T>

public Lazy<List<Object>> Years { get; set; } = new Lazy<List<object>>(() =>
{
   List<object> retList = new List<object>();
   for (byte i = 0; i < 50; i++)
   {
      retList.Add(new { Value = i, Name = (2000 + i).ToString() });
   }
   return retList;
});

或用Enumerable.Range

private List<Object> Years { get; set; }
   = Enumerable.Range(0, 50)
               .Select(i => (object)new { Value = i, Name = (2000 + i).ToString() })
               .ToList();

注意 :整个List<object>似乎还是有点可疑

或者也许更简洁一些是值元组

private List<(int Value, string Name)> Years { get; set; }
   = Enumerable.Range(0, 50)
               .Select(i => (i, (2000 + i).ToString()))
               .ToList();