Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在构造函数和定义中设置变量_C#_Class_Declaration - Fatal编程技术网

C# 在构造函数和定义中设置变量

C# 在构造函数和定义中设置变量,c#,class,declaration,C#,Class,Declaration,注意以下几点 //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 publi

注意以下几点

//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较短,但在编译期间效率较低

与在构造函数中声明变量相比,在“set”的定义中设置变量有什么优势或特殊原因吗

不,事实上,这可能根本不是你想要的。这将使得不可能像任何调用那样设置“break”或“cheese”,例如
bread=“raye”,将其设置为“Amoroso”(如果它工作,但会导致
堆栈溢出异常
)。还要注意,尝试检索代码中的值将导致出现
StackOverflowException
,并且属性getter返回属性,而不是备份字段值

你可能会这样想:

public class Cheesesteak
{
    private string bread = "Amoroso";
    public string Bread 
    {
        get {return bread;}
        set 
        {
            bread = value;
        }
    }

    // ...
这里唯一的优点是在定义字段时设置“默认”值,这在某些情况下有助于提高可维护性或可读性,甚至可能消除对已定义构造函数的需求,这可能会减少代码的总长度

我的初步猜测是模式1较短,但在编译期间效率较低

通常,内联设置字段与在构造函数中设置字段并不会降低效率。编译器将使类型的实际构造函数首先设置字段,然后运行构造函数代码,因此两个版本最终在编译的IL方面是相同的(出于实际目的)。这不是效率问题,而是代码可读性和可维护性问题

请注意,如果您希望属性始终为常量(即:
Bread
始终返回
“Amoroso”
),则只需使属性具有一个getter而不具有setter:

public string Bread { get { return "Amoroso"; } }

我怀疑情况并非如此,但我想我还是把它作为一个选项提出来,以防万一它是您想要的。

好吧,第二个选项将导致
StackOverflowException
每当用户试图分配访问属性时,而第一个选项只允许私人访问属性

你的意思可能是:

private string bread = "Amaroso";
public string Bread
{
    get { return bread; }
    private set
    {
        bread = value;
    }
}

将使用“Amaroso”初始化属性,但不允许公开设置

不,他们完全不同。
get
set
块实际上是在读取或写入属性时执行的方法。它们中的任何一个都与初始化有关

var x = thing.Property; // Property's "get" accessor method is executed
thing.Property = x; // Property's "set" accessor method is executed

在第二个示例中,两个属性访问器都将在其自身上无限递归,您将得到StackOverflowException。

模式2是堆栈溢出。@SLaks..鉴于此站点的名称,这似乎合适吗?:PFLAGED as duplicate of:请阅读此处的注释/答案。以及当用户尝试检索属性值时。这两个访问器都是等待爆炸的SOE陷阱。@ReedCopsey实际上,它们都会导致SOE。“getter和setter都无限地在自己身上递归。”NominSim我重写为explicit@ReedCopsey正如罗伯塔维所说的那样,+1并不意味着痛苦,只是想确保OP知道它有多坏。