new 运算符创建类型的新实例。new 关键字还可用作成员声明修饰符或泛型类型约束。

构造函数调用

要创建类型的新实例,通常使用 new 运算符调用该类型的某个构造函数:

static void Main(string[] args)
   {
   var dict = new Dictionary < string , int >
        {
            [ "第一" ] = 10 ,
            [ "第二" ] = 20 ,
            [ "第三" ] = 30 ,
         };

    Console . WriteLine ( string . Join ( ";" , dict . Select ( entry => $"{entry . Key}:{entry . Value}" ) ) );
    // 输出:
    // 第一:10;第二:20;第三:30
    }

可以使用带有 new 运算符的对象或集合初始值设定项实例化和初始化一个语句中的对象,如下例所示:

var dict = new Dictionary < string , int >
    [ "第一" ] = 10 ,
    [ "第二" ] = 20 ,
    [ "第三" ] = 30 ,
Console . WriteLine ( string . Join ( ";" , dict . Select ( entry => $"{entry . Key}:{entry . Value}")));
// 输出:
// 第一:10;第二:20;第三:30

目标类型化 new

构造调用表达式由目标确定类型。也就是说,如果已知表达式的目标类型,则可以省略类型名称,如下面的示例所示:

List < int > xs = new ( );
List < int > ys = new ( capacity: 10_000 );
List < int > zs = new ( ) { Capacity = 20_000 };

Dictionary < int , List < int > > lookup = new ( )
{
    [ 1 ] = new ( ) { 1 , 2 , 3 },
    [ 2 ] = new ( ) { 5 , 8 , 3 },
    [ 5 ] = new ( ) { 1 , 0 , 4 }
};

如前面的示例所示,在由目标确定类型的 new 表达式中始终使用括号。

如果 new 表达式的目标类型未知(例如使用 var 关键字时),必须指定类型名称。

数组创建

还可以使用 new 运算符创建数组实例,如下例所示:

var numbers = new int [ 3 ];
numbers [ 0 ] = 10;
numbers [ 1 ] = 20;
numbers [ 2 ] = 30;
Console . WriteLine ( string . Join ( "," , numbers ) );
// 输出:
// 10,20,30

使用数组初始化语法创建数组实例,并在一个语句中使用元素填充该实例。以下示例显示可以执行该操作的各种方法:

var a = new int [ 3 ] { 10, 20, 30 };
var b = new int [ ] { 10, 20, 30 };
var c = new [ ] { 10, 20, 30 };
Console . WriteLine ( c . GetType ( ) );  // 输出:System . Int32 [ ]

匿名类型的实例化

要创建匿名类型的实例,请使用 new 运算符和对象初始值设定项语法:

var example = new { Greeting = "Hello", Name = "World" };
Console . WriteLine ( $"{example . Greeting},{example . Name}!" );
// 输出:
// Hello,World!

类型实例的析构

无需销毁此前创建的类型实例。引用和值类型的实例将自动销毁。包含值类型的上下文销毁后,值类型的实例随之销毁。在引用类型的最后一次引用被删除后,垃圾回收器会在某个非指定的时间销毁其实例。

对于包含非托管资源的类型实例(例如,文件句柄),建议采用确定性的清理来确保尽快释放其包含的资源。

运算符可重载性

用户定义的类型可以重载 new 运算符。

new 的重载

用户定义类型不能重载 new 操作符。


兔子码农
4 声望1 粉丝

一个酒晕子