C# 道具中的私有初始化?
private init in C# props?
C# 中 init only setter 的 private
访问修饰符是什么意思?对于我域 类 中的大多数属性,我通常将 setter 设为私有。 init
,有关系吗?
以下似乎没有任何问题,编译器没有报错。
public class Point
{
public int X { get; private init; }
public int Y { get; private init; }
}
所以上面和下面有什么不同。下面没有私信。
public class Point
{
public int X { get; init; }
public int Y { get; init; }
}
它会影响 setter 的调用位置,就像正常的 setter 一样。
考虑这段代码:
public class Point
{
public int X { get; private init; }
public int Y { get; private init; }
}
class Program
{
static void Main()
{
var point = new Point { X = 10, Y = 20 };
}
}
因两个编译时错误而失败:
The property or indexer 'Point.X' cannot be used in this context because the set accessor is inaccessible
(以及 Y
的等价物)。
相同的初始值设定项在 和 Point
class 中是有效的,因为可以在那里访问集合访问器。例如,您可能想要使用 public 工厂方法,它是通过对象初始值设定项实现的:
public class Point
{
public int X { get; private init; }
public int Y { get; private init; }
public static Point FromXY(int x, int y) =>
new Point { X = x, Y = y };
}
(有多种原因导致这可能不理想,或者您可能更愿意将参数添加到私有构造函数,但这是 一个示例 私有 init-only setter 可以访问。)
同样,如果没有 set 访问器的 private
部分,上面的代码也是有效的,因为它们可以从任何地方调用(作为对象初始化程序的一部分)。
在 c# 9.0 中添加了 init
关键字,以便在对象上添加不可变属性。
我们曾经遇到的问题是,如果您有这个对象,您仍然可以通过 public 方法修改名称 属性(尽管它有一个私有的 setter)。例如:
public class Person
{
public Person(string name)
{
this.Name = name;
}
public void SetName(string name)
{
this.Name = name;
}
public string Name { get; private set; }
}
而且我们也不能使用对象初始化器
var person = new Person
{
Name = "Jane Doe" // Compile Error
};
现在,如果我们将代码更改为使用 init
public class Person
{
public Person(string name)
{
this.Name = name;
}
public string Name { get; init; }
}
我们现在可以使用对象初始化器
var person = new Person
{
Name = "Jane Doe" // No error
};
但是,如果我们像您的示例一样使用您的private init
public class Person
{
public Person(string name)
{
this.Name = name;
}
public string Name { get; private init; }
}
我们将无法使用对象初始化器
var person = new Person
{
Name = "Jane Doe" // Compile error
};
C# 中 init only setter 的 private
访问修饰符是什么意思?对于我域 类 中的大多数属性,我通常将 setter 设为私有。 init
,有关系吗?
以下似乎没有任何问题,编译器没有报错。
public class Point
{
public int X { get; private init; }
public int Y { get; private init; }
}
所以上面和下面有什么不同。下面没有私信。
public class Point
{
public int X { get; init; }
public int Y { get; init; }
}
它会影响 setter 的调用位置,就像正常的 setter 一样。
考虑这段代码:
public class Point
{
public int X { get; private init; }
public int Y { get; private init; }
}
class Program
{
static void Main()
{
var point = new Point { X = 10, Y = 20 };
}
}
因两个编译时错误而失败:
The property or indexer 'Point.X' cannot be used in this context because the set accessor is inaccessible
(以及 Y
的等价物)。
相同的初始值设定项在 和 Point
class 中是有效的,因为可以在那里访问集合访问器。例如,您可能想要使用 public 工厂方法,它是通过对象初始值设定项实现的:
public class Point
{
public int X { get; private init; }
public int Y { get; private init; }
public static Point FromXY(int x, int y) =>
new Point { X = x, Y = y };
}
(有多种原因导致这可能不理想,或者您可能更愿意将参数添加到私有构造函数,但这是 一个示例 私有 init-only setter 可以访问。)
同样,如果没有 set 访问器的 private
部分,上面的代码也是有效的,因为它们可以从任何地方调用(作为对象初始化程序的一部分)。
在 c# 9.0 中添加了 init
关键字,以便在对象上添加不可变属性。
我们曾经遇到的问题是,如果您有这个对象,您仍然可以通过 public 方法修改名称 属性(尽管它有一个私有的 setter)。例如:
public class Person
{
public Person(string name)
{
this.Name = name;
}
public void SetName(string name)
{
this.Name = name;
}
public string Name { get; private set; }
}
而且我们也不能使用对象初始化器
var person = new Person
{
Name = "Jane Doe" // Compile Error
};
现在,如果我们将代码更改为使用 init
public class Person
{
public Person(string name)
{
this.Name = name;
}
public string Name { get; init; }
}
我们现在可以使用对象初始化器
var person = new Person
{
Name = "Jane Doe" // No error
};
但是,如果我们像您的示例一样使用您的private init
public class Person
{
public Person(string name)
{
this.Name = name;
}
public string Name { get; private init; }
}
我们将无法使用对象初始化器
var person = new Person
{
Name = "Jane Doe" // Compile error
};