组合列表初始值设定项和对象初始值设定项

发布于 2024-11-14 06:05:43 字数 383 浏览 1 评论 0原文

是否可以同时组合列表初始值设定项和对象初始值设定项? 给出以下类定义:

class MyList : List<int>
{
    public string Text { get; set; }
}

// we can do this
var obj1 = new MyList() { Text="Hello" };

// we can also do that
var obj2 = new MyList() { 1, 2, 3 };

// but this one doesn't compile
//var obj3 = new MyList() { Text="Hello", 1, 2, 3 };

这是设计使然还是只是 c# 编译器的错误或缺失功能?

Is is possible to combine a List initializer and object initializer at the same time?
Given the following class definition:

class MyList : List<int>
{
    public string Text { get; set; }
}

// we can do this
var obj1 = new MyList() { Text="Hello" };

// we can also do that
var obj2 = new MyList() { 1, 2, 3 };

// but this one doesn't compile
//var obj3 = new MyList() { Text="Hello", 1, 2, 3 };

Is this by design or is it just a bug or missing feature of the c# compiler?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

别再吹冷风 2024-11-21 06:05:43

不,查看 C# 规范第 7.6.10 节中的定义,object-or-collection-initializer 表达式是object-initializer code> 一个集合初始化器

object-initializer 由多个 member-initializer 组成,每个成员的形式为 initializer =initializer-valuemember-initializer >collection-initializer由多个element-initializer组成,每个元素初始化器都是一个non-assigment-expression

所以它看起来像是设计使然——可能是为了简单起见。老实说,我不能说我曾经想要这样做。 (我通常不会从 List 开始 - 我会编写它。)我真的不想看到:

var obj3 = new MyList { 1, 2, Text = "Hello", 3, 4 };

编辑:如果你真的,真的 想要启用此功能,您可以将其放入类中:

class MyList : List<int>
{
    public string Text { get; set; }
    public MyList Values { get { return this; } }
}

此时您可以编写:

var obj3 = new MyList { Text = "Hello", Values = { 1, 2, 3, 4 } };

No, looking at the definitions from section 7.6.10 of the C# spec, an object-or-collection-initializer expression is either an object-initializer or a collection-initializer.

An object-initializer is composed of multiple member-initializers, each of which is of the form initializer = initializer-value whereas a collection-initializer is composed of multiple element-initializers, each of which is a non-assigment-expression.

So it looks like it's by design - possibly for the sake of simplicity. I can't say I've ever wanted to do this, to be honest. (I usually wouldn't derive from List<int> to start with - I'd compose it instead.) I would really hate to see:

var obj3 = new MyList { 1, 2, Text = "Hello", 3, 4 };

EDIT: If you really, really want to enable this, you could put this in the class:

class MyList : List<int>
{
    public string Text { get; set; }
    public MyList Values { get { return this; } }
}

at which point you could write:

var obj3 = new MyList { Text = "Hello", Values = { 1, 2, 3, 4 } };
随梦而飞# 2024-11-21 06:05:43

不,这不是错误。这是语言设计的。

当您编写

var obj1 = new MyList() { Text="Hello" };

此代码时,编译器会有效地将其转换为

MyList temp = new MyList();
temp.Text = "Hello";
MyList obj = temp;

当您编写

var obj2 = new MyList() { 1, 2, 3 };

此代码时,编译器会有效地将其转换为 请

MyList temp = new MyList();
temp.Add(1);
temp.Add(2);
temp.Add(3);
MyList obj2 = temp;

注意,在第一种情况下,您使用的是对象初始值设定项,但在第二种情况下,您使用的是集合初始值设定项。不存在对象和集合初始化器这样的东西。您要么正在初始化对象的属性,要么正在初始化集合。你不能两者兼而有之,这是设计使然。

另外,您不应该从 List 派生。请参阅:继承列表实现集合是一个坏主意吗?

No, it's a not a bug. It is by design of the language.

When you write

var obj1 = new MyList() { Text="Hello" };

this is effectively translated by the compiler to

MyList temp = new MyList();
temp.Text = "Hello";
MyList obj = temp;

When you write

var obj2 = new MyList() { 1, 2, 3 };

this is effectively translated by the compiler to

MyList temp = new MyList();
temp.Add(1);
temp.Add(2);
temp.Add(3);
MyList obj2 = temp;

Note that in the first case you are using an object initializer, but in the second case you are using a collection initializer. There is no such thing as an object-and-collection intializer. You are either initializing the properties of your object, or you are initializing the collection. You can not do both, this is by design.

Also, you shouldn't derive from List<T>. See: Inheriting List<T> to implement collections a bad idea?

我们的影子 2024-11-21 06:05:43

如果您想获得类似的功能,请考虑使用构造函数参数:

var x = new CustomList("Hello World") { 1, 2, 3 }

If you want to get something like this functionality, consider making a constructor argument:

var x = new CustomList("Hello World") { 1, 2, 3 }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文