这些只是在 C# 中使用对象初始化来实例化对象的两种可接受的等效语法(如果您只是在做 var cat = new Cat();,则不能省略括号)。
- 由于您的类没有显式构造函数,因此为 Cat 类提供了一个默认的无参数构造函数
-
new Cat {...} 允许实例化和初始化 Cat 对象的属性作为new Cat() {...} 的快捷方式,调用提到的构造函数。
关于构造函数的部分很重要。如果没有隐式默认构造函数/显式无参数构造函数,那么你不能省略括号,无论如何你都必须在其中提供参数:
public class Cat {
public string Name;
public int Age;
public Cat(string s) { // since I provide a constructor with parameter here, no parameterless constructor exists
Name = s;
}
}
// ...
void TestCat()
{
// compilation error : 'Cat'' does not contain a constructor that takes 0 arguments
//var badCat1 = new Cat { Name = "Felix", Age = 3} ;
//var badCat2 = new Cat() { Name = "Felix", Age = 3} ;
// works (but no way to remove parenthesis here, since there are parameters to pass to csontructor)
var goodCat = new Cat("Felix") { Age = 3 } ;
Console.WriteLine($"The cat {goodCat.Name} is {goodCat.Age} years old");
}
特殊情况:(在集合、列表、字典等方面经常使用...)。
如果一个类 T 实现了 IEnumerable(即有一个 IEnumerable
GetEnumerator() 公共函数),并实现一个 Add 方法,然后对象初始化器将使用 Add 方法与集合进行枚举。
来自https://blog.mariusschulz.com/2014/06/26/fun-with-custom-c-collection-initializers的示例
创建特殊类“Points”,其作用类似于初始化时的“List”。
请注意,这也使用了现有的无参数构造函数!
public class Points : IEnumerable<Point3D>
{
private readonly List<Point3D> _points;
public Points()
{
_points = new List<Point3D>();
}
public void Add(double x, double y, double z)
{
_points.Add(new Point3D(x, y, z));
}
public IEnumerator<Point3D> GetEnumerator()
{
return _points.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
这样使用:
var cube = new Points
{
{ -1, -1, -1 },
{ -1, -1, 1 },
{ -1, 1, -1 },
{ -1, 1, 1 },
{ 1, -1, -1 },
{ 1, -1, 1 },
{ 1, 1, -1 },
{ 1, 1, 1 }
};