请注意以下内容......
//pattern 1
public class Cheesesteak
{
public string bread {get; private set}
public string cheese {get; private set}
public Cheesesteak()
{
bread = "Amoroso";
cheese = "Cheez Whiz";
}
}
//pattern 2
public class Cheesesteak
{
public string bread
{
get {return bread;}
set
{
bread = "Amoroso";
}
}
public string cheese
{
get {return cheese;}
set
{
cheese = "Cheez Whiz";
}
}
public Cheesesteak() {}
}
这是一个好奇心问题。是否有任何优势或特殊原因可以在“set”的定义中设置变量而不是在构造函数中声明它们?我最初的猜测是模式1更短,但在编译期间效率较低。
答案 0 :(得分:8)
是否有任何优势或特殊原因可以在“set”的定义中设置变量而不是在构造函数中声明它们?
不,事实上,这可能不是你想要的。这将使得无法设置“break”或“cheese”,因为任何调用(例如bread = "rye";
)都会将其设置为“Amoroso”(如果它有效,但会导致StackOverflowException
)。另请注意,尝试检索代码中的值将导致StackOverflowException
,而属性getter将返回属性,而不是返回支持字段值。
你可能会想到这个:
public class Cheesesteak
{
private string bread = "Amoroso";
public string Bread
{
get {return bread;}
set
{
bread = value;
}
}
// ...
这里唯一的优点是你在定义字段时设置“默认”值,这在某些情况下有助于可维护性或可读性,甚至可能消除对定义的构造函数的需求,这可能会降低整体代码长度。
我最初的猜测是模式1更短,但在编译期间效率较低。
通常,在构造函数中设置字段内联与设置它们不会降低效率。编译器将使类型的实际构造函数首先设置字段然后运行构造函数代码,因此两个版本最终(出于实际目的)在编译的IL方面相同。这不是效率问题,而是代码可读性和可维护性。
请注意,如果您希望该属性始终为常量(即:Bread
始终返回"Amoroso"
),您可以让该属性具有getter没有二传手:
public string Bread { get { return "Amoroso"; } }
我怀疑情况并非如此,但我认为我会把它作为一种选择,以防它是你想要的。
答案 1 :(得分:1)
第二个选项会在用户尝试分配或访问属性时生成StackOverflowException
,而第一个选项只允许私有访问属性。
你可能意味着:
private string bread = "Amaroso";
public string Bread
{
get { return bread; }
private set
{
bread = value;
}
}
将使用“Amaroso”初始化该属性,但不允许将其公开设置。
答案 2 :(得分:0)
get
和set
块实际上是在读取或写入属性时执行的方法。其中有一些任何与初始化有关。
var x = thing.Property; // Property's "get" accessor method is executed
thing.Property = x; // Property's "set" accessor method is executed
在你的第二个例子中,两个属性访问器都会无限递归,你会得到一个StackOverflowException。