在自定义类型上使用集合初始值设定项语法?
我有一个很大的静态列表,它基本上是一个查找表,所以我在代码中初始化该表。
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 具有更多属性,因此我添加了一个构造函数以允许更紧凑的初始化格式:
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()
。例如:
private static List<LookupItem> _lookupTable = new List<LookupItem>()
{
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
//etc
}
这可能吗?我喜欢认为这是因为 Dictionary
的 KeyValuePair
可以通过这种方式初始化。
MSDN 指出:
集合初始值设定项可让您指定一个或多个元素 当你初始化一个实现了的集合类时的初始化器 IEnumerable。元素初始值设定项可以是一个简单的值, 表达式或对象初始值设定项。通过使用集合初始值设定项 您不必指定多次调用 Add 方法 源代码中的类;编译器添加调用。
这是否意味着我需要在我的 LookupItem 类上实现 IEnumerable 并返回每个参数?不过,我的班级不是收藏班级。
I have a large static list which is basically a lookup table, so I initialise the table in code.
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
}
}
The real LookupItem
has many more properties, so I added a constructor to allow for a more compact initialisation format:
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
}
}
What I'd really like to do is use the collection initialiser format for the object itself so I can get rid of the new LookupItem()
on every line. eg:
private static List<LookupItem> _lookupTable = new List<LookupItem>()
{
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
//etc
}
Is this possible? I like to think it is because the KeyValuePair
's of a Dictionary<>
can be initialised in this way.
MSDN States:
Collection initializers let you specify one or more element
intializers when you initialize a collection class that implements
IEnumerable. The element initializers can be a simple value, an
expression or an object initializer. By using a collection initializer
you do not have to specify multiple calls to the Add method of the
class in your source code; the compiler adds the calls.
Does this mean I need to implement IEnumerable
on my LookupItem
class and return each parameter? My class isn't a collection class though.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我认为你需要创建一个自定义集合而不是列表。例如,将其称为 LookupItemTable。为该集合提供一个 Add(int, int, float, float) 方法并让它实现 IEnumerable。例如:
我现在已经尝试了上面的代码,它似乎对我有用。
I think you need to make a custom collection instead of List. Call it LookupItemTable, for example. Give that collection an Add(int, int, float, float) method and have it implement IEnumerable. For example:
I've now tried the above code and it seems to work for me.
快速修复:使用带有多个参数的
Add
重载创建您自己的List
类型:现在完全按照您想要的方式工作:
更基本答案:
您混淆了对象初始值设定项 和 集合初始值设定项。简而言之:
对象初始值设定项是一种语法技巧,它在后台为具有指定值的每个命名属性调用属性设置方法。
集合初始值设定项是一种语法技巧,在后台:
Array
类型:用项目填充数组IEnumerable< /code>:为每个子括号集调用
Add
方法。这就是它的全部内容。例如,考虑以下黑客:
您永远不应该在真实的程序中执行此操作,但我希望检查此示例和结果,特别是如果您调试单步调试它,将帮助您清楚地理解初始化程序并为您当前的选择一个好的解决方案设想。
Quick fix : Make your own
List
type with anAdd
overload that takes multiple arguments:Now works exactly as you want:
More fundamental answer:
You're mixing up object initializers and collection initializers. Put simply:
Object initializers are a syntactic trick that, in the background call the property set methods for each named property with the value specified.
Collection initializers are a syntactic trick that, in the background:
Array
type: Fill the array with the itemsIEnumerable
: Call theAdd
method for each sub-bracketed set.That is all there is to it. Consider for example the following hack:
You should never do this in a real program, but I hope examining this example and the results, especially if you debug step through it, will help you understand the initializers clearly and choose a good solution for your current scenario.
您尝试在列表本身而不是您的类型上使用集合初始值设定项:
因此它在
List
上寻找带有四个参数的Add
方法,并且那不存在。您必须实现自己的集合类才能使用自定义集合初始值设定项。当您使用
List
时,您会陷入构造函数调用的困境。You're trying to use a collection initializer on the list itself, not on your type:
So it's looking for an
Add
method with four parameters onList<T>
, and that doesn't exist.You would have to implement your own collection class to use a custom collection initializer. While you're using
List<T>
, you're stuck with the constructor calls you've got.不要使用从 List派生的自定义类来掩盖 List 的意图,而是添加一个调用所需构造函数的简单扩展:
请注意,您是为了简洁而牺牲清晰度,因此使用风险自负。使用“new ListItem”可以让您直接按 F12 进入构造函数;这个扩展不会(对于其他开发人员来说也不会是显而易见的)。
Rather than obscure the intent of List with a custom class deriving from List<LookupItem>, add a simple extension that calls the required constructor:
Note that you're trading clarity for brevity, so use at your own risk. Using "new ListItem" lets you F12 directly to the constructor; this extension does not (nor will it ever likely be obvious to other developers).
不,这意味着
List
实现了IEnumerable
,这就是为什么你可以写它也意味着如果你的
LookupItem
是一个集合,实现了IEnumerable
,你可以这样写:No, it means that
List<LookupItem>
implementsIEnumerable
, which is why you can writeIt also means that if your
LookupItem
was a collection that implementedIEnumerable
, you could have written: