首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在自定义类型上使用集合初始化器语法?

在自定义类型上使用集合初始化器语法?
EN

Stack Overflow用户
提问于 2012-02-08 13:36:27
回答 4查看 8.8K关注 0票数 11

我有一个大的静态列表,它基本上是一个查找表,所以我用代码初始化了这个表。

代码语言:javascript
复制
private class MyClass
{
    private class LookupItem
    {
        public int Param1    { get; set; }
        public int Param2    { get; set; }
        public float Param2  { get; set; }
        public float Param4  { get; set; }
    }

    private static List<LookupItem> _lookupTable = new List<LookupItem>()
    { 
        new LookupItem() { Param1 = 1, Param2 = 2, Param3 = 3 Param4 = 4 },
        new LookupItem() { Param1 = 5, Param2 = 6, Param3 = 7 Param4 = 8 },
        //etc
    }
}

真正的LookupItem有更多的属性,因此我添加了一个构造函数,以支持更紧凑的初始化格式:

代码语言:javascript
复制
private class MyClass
{
    private class LookupItem
    {
        public int Param1    { get; set; }
        public int Param2    { get; set; }
        public float Param2  { get; set; }
        public float Param4  { get; set; }

        public LookupItem(int param1, int param2, float param3, float param4)
        {
            Param1 = param1;
            Param2 = param2;
            Param3 = param3;
            Param4 = param4;    
        }
    }

    private static List<LookupItem> _lookupTable = new List<LookupItem>()
    { 
        new LookupItem(1, 2, 3, 4),
        new LookupItem(5, 6, 7, 8),
        //etc
    }
}

我真正想要做的是对对象本身使用集合初始化器格式,这样我就可以在每一行中去掉new LookupItem()。例:

代码语言:javascript
复制
private static List<LookupItem> _lookupTable = new List<LookupItem>()
{ 
    { 1, 2, 3, 4 },
    { 5, 6, 7, 8 },
    //etc
}

这个是可能的吗?我认为这是因为Dictionary<>Dictionary<>可以以这种方式初始化。

MSDN国家:

集合初始化器可以在初始化实现的IEnumerable集合类时指定一个或多个元素intializers。元素初始化器可以是简单值、表达式或对象初始化器。通过使用集合初始化器,您不必在源代码中指定对类的Add方法的多个调用;编译器将添加这些调用。

这是否意味着我需要在我的IEnumerable类上实现LookupItem并返回每个参数?不过,我的课不是集合类。

EN

回答 4

Stack Overflow用户

发布于 2012-02-08 14:23:04

快速修复:使用包含多个参数的Add重载创建自己的List类型:

代码语言:javascript
复制
class LookupList : List<LookupItem> {
    public void Add(int Param1, int Param2, ... sometype ParamX) {
        this.Add(new LookupItem() { Param1 = Param1, Param2 = Param2, ... ParamX = ParamX });
    }
}

现在完全按照您的要求工作:

代码语言:javascript
复制
    private static LookupList _lookupTable = new LookupList() {                  
        {1,2,3,4},                 
        {2,7,6,3}                
    };

更基本的答案:

你把对象初始化器集合初始化器混在一起了。简单地说:

对象初始化器是一个语法技巧,在后台为每个指定值的命名属性调用属性集方法。

集合初始化器是一个语法技巧,在后台:

  • 对于Array类型:用项填充数组
  • 对于任何其他类型,必须实现IEnumerable:为每个子括号中的集合调用Add方法。

这就是它的全部。例如,考虑以下黑客:

代码语言:javascript
复制
public class Hack : IEnumerable {
    public int LuckyNumber { get; set; }
    public double Total { get; private set; }
    public void Add(string message, int operand1, double operand2, double operand3) {
        Console.WriteLine(message);
        this.Total += operand1 * operand2 - operand3;
    }
    public IEnumerator GetEnumerator() { throw new NotImplementedException(); }
}

class Program {
    static void Main(string[] args) {
        Hack h1 = new Hack() {
            { "Hello", 1, 3, 2},
            { "World", 2, 7, 2.9}
        };
        Console.WriteLine(h1.Total);
        Hack h2 = new Hack() { LuckyNumber = 42 };
        Console.WriteLine(h2.LuckyNumber);
    }
}

您不应该在真正的程序中这样做,但是我希望研究这个示例和结果,尤其是调试步骤,将有助于您清楚地理解初始化器,并为当前的场景选择一个好的解决方案。

票数 6
EN

Stack Overflow用户

发布于 2012-02-08 13:42:39

您试图在列表本身上使用集合初始化程序,而不是在您的类型上使用:

代码语言:javascript
复制
// Note the "new List<...>" part - that specifies what type the collection
// initializer looks at...
private static List<LookupItem> _lookupTable = new List<LookupItem>()
{ 
    { 1, 2, 3, 4 },
    { 5, 6, 7, 8 },
}

因此,它正在寻找一个在Add上具有四个参数的List<T>方法,而这个方法并不存在。

您必须实现自己的集合类才能使用自定义集合初始化器。当您使用List<T>时,您将被困在构造函数调用中。

票数 4
EN

Stack Overflow用户

发布于 2019-01-02 20:06:27

与其用从List派生的自定义类来掩盖List的意图,不如添加一个简单的扩展来调用所需的构造函数:

代码语言:javascript
复制
public static class LookupItemListExtensions
{
    public static void Add(this List<LookupItem> lookupItemList, int param1, int param2, float param3, float param4)
    {
        lookupItemList.Add(new LookupItem(param1, param2, param3, param4));
    }
}

注意,你是在用清晰来换取简洁,所以你要冒着自己的风险去使用。使用"new“使您可以直接使用F12构造函数;这个扩展不允许(其他开发人员也不太清楚)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9194363

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档