对象初始值设定项语法混乱。在初始化程序中使用括号?
Object initializer syntax confusion. Using parentheses in initializer?
所以我正在查看 the documentation 以了解如何使用对象初始值设定项,无论是否用于匿名类型。我唯一想知道的是为什么(如果重要的话)例子中有什么不同。
它是这样的:对于一只猫
class Cat
{
public int Age { get; set; }
public string Name { get; set; }
}
我可以看到第一个例子:
Cat cat = new Cat { Age = 10, Name = "Fluffy" };
这是有道理的。但是,您可以找到以下内容:
List<Cat> cats = new List<Cat>
{
new Cat(){ Name = "Sylvester", Age=8 },
new Cat(){ Name = "Whiskers", Age=2 }
};
现在我的问题是:(为什么)new Cat{...}
和 new Cat(){...}
?
为什么要使用(或不使用)括号?
这些只是 C# 中对象实例化的两个可接受的等价语法 对象初始化 (如果你只是做 var cat = new Cat();
,你不能省略括号) .
- 由于您的 class 没有显式构造函数,因此向 Cat class
提供了一个默认的无参数构造函数
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");
}
特例 : (常用于集合、列表、字典等...)。
如果 class T 实现了 IEnumerable(即有一个 IEnumerable
GetEnumerator() public 函数),并实现一个 Add 方法,然后对象初始化器 将使用 Add 方法 枚举集合。
示例来自 https://blog.mariusschulz.com/2014/06/26/fun-with-custom-c-collection-initializers
创建特殊的 class "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 }
};
如果一个对象有一个无参数构造函数,您可以省略括号。所以这两个都是有效的
// Assuming cat has a constructor with no parameters
Cat cat = new Cat { Age = 10, Name = "Fluffy" };
Cat cat = new Cat() { Age = 10, Name = "Fluffy" };
List<T>
本身有一个对象初始化器,您可以在其中提供任意数量的项目,它们会自动添加到集合中。
List<Cat> cats = new List<Cat>()
{
new Cat(){ Name = "Sylvester", Age=8 }, // Add sylvester to the List
new Cat(){ Name = "Whiskers", Age=2 } // And Whiskers too
};
如上所述,您也可以在此处删除括号
List<Cat> cats = new List<Cat>
{
new Cat { Name = "Sylvester", Age=8 }, // Add sylvester to the List
new Cat { Name = "Whiskers", Age=2 } // And Whiskers too
};
所以我正在查看 the documentation 以了解如何使用对象初始值设定项,无论是否用于匿名类型。我唯一想知道的是为什么(如果重要的话)例子中有什么不同。
它是这样的:对于一只猫
class Cat
{
public int Age { get; set; }
public string Name { get; set; }
}
我可以看到第一个例子:
Cat cat = new Cat { Age = 10, Name = "Fluffy" };
这是有道理的。但是,您可以找到以下内容:
List<Cat> cats = new List<Cat>
{
new Cat(){ Name = "Sylvester", Age=8 },
new Cat(){ Name = "Whiskers", Age=2 }
};
现在我的问题是:(为什么)new Cat{...}
和 new Cat(){...}
?
为什么要使用(或不使用)括号?
这些只是 C# 中对象实例化的两个可接受的等价语法 对象初始化 (如果你只是做 var cat = new Cat();
,你不能省略括号) .
- 由于您的 class 没有显式构造函数,因此向 Cat class 提供了一个默认的无参数构造函数
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");
}
特例 : (常用于集合、列表、字典等...)。
如果 class T 实现了 IEnumerable(即有一个 IEnumerable GetEnumerator() public 函数),并实现一个 Add 方法,然后对象初始化器 将使用 Add 方法 枚举集合。
示例来自 https://blog.mariusschulz.com/2014/06/26/fun-with-custom-c-collection-initializers
创建特殊的 class "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 }
};
如果一个对象有一个无参数构造函数,您可以省略括号。所以这两个都是有效的
// Assuming cat has a constructor with no parameters
Cat cat = new Cat { Age = 10, Name = "Fluffy" };
Cat cat = new Cat() { Age = 10, Name = "Fluffy" };
List<T>
本身有一个对象初始化器,您可以在其中提供任意数量的项目,它们会自动添加到集合中。
List<Cat> cats = new List<Cat>()
{
new Cat(){ Name = "Sylvester", Age=8 }, // Add sylvester to the List
new Cat(){ Name = "Whiskers", Age=2 } // And Whiskers too
};
如上所述,您也可以在此处删除括号
List<Cat> cats = new List<Cat>
{
new Cat { Name = "Sylvester", Age=8 }, // Add sylvester to the List
new Cat { Name = "Whiskers", Age=2 } // And Whiskers too
};