What is the { get; set; } syntax in C#?
我正在学习ASP.NET MVC,我可以阅读英文文档,但我不太了解此代码的情况:
1 2 3 4 | public class Genre { public string Name { get; set; } } |
这是什么意思:
它是所谓的自动属性,本质上是以下内容的简写(类似的代码将由编译器生成):
1 2 3 4 5 6 7 8 9 10 11 12 | private string name; public string Name { get { return this.name; } set { this.name = value; } } |
据我所知,
1 2 3 4 5 6 7 8 9 | public class Genre { private string name; // This is the backing field public string Name // This is your property { get => name; set => name = value; } } |
然而,如果你像我一样——大约一个小时前——你并不真正了解什么是属性和访问器,你也不太了解一些基本术语。msdn是一个很好的学习工具,但是对于初学者来说,它并不总是容易理解的。所以我会在这里更深入地解释这一点。
不可否认,上面的陈述非常令人困惑,所以让我们来看一些例子。假设这个代码是指音乐的流派。所以在课堂类型中,我们需要不同类型的音乐。假设我们想要三种类型:嘻哈、摇滚和乡村音乐。为此,我们将使用类的名称来创建该类的新实例。
1 2 3 4 5 6 7 8 | Genre g1 = new Genre(); //Here we're creating a new instance of the class"Genre" //called g1. We'll create as many as we need (3) Genre g2 = new Genre(); Genre g3 = new Genre(); //Note the () following new Genre. I believe that's essential since we're creating a //new instance of a class (Like I said, I'm a beginner so I can't tell you exactly why //it's there but I do know it's essential) |
现在我们已经创建了流派类的实例,我们可以使用上面设置的"name"属性设置流派名称。
1 2 | public string Name //Again, this is the 'Name' property { get; set; } //And this is the shorthand version the process we're doing right now |
我们可以通过编写以下内容将"g1"的名称设置为hip hop
1 | g1.Name ="Hip Hop"; |
这里发生的事情有点复杂。如我之前所说,
1 2 3 4 5 6 7 8 9 10 11 | public class g1 //We've created an instance of the Genre Class called"g1" { private string name; public string Name { get => name; set => name ="Hip Hop"; //instead of 'value',"Hip Hop" is written because //'value' in 'g1' was set to"Hip Hop" by previously //writing 'g1.Name ="Hip Hop"' } } |
需要注意的是,上面的示例实际上不是用代码编写的。它更像是一个假设性的代码,它代表了在后台发生的事情。
既然我们已经设置了g1类型实例的名称,我相信我们可以通过编写
1 2 3 | console.WriteLine (g1.Name); //This uses the 'get' function from our 'Name' Property //and returns the field 'name' which we just set to //"Hip Hop" |
如果我们运行这个,我们将在控制台中得到
因此,为了这个解释的目的,我将用输出来完成这个例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | using System; public class Genre { public string Name { get; set; } } public class MainClass { public static void Main() { Genre g1 = new Genre(); Genre g2 = new Genre(); Genre g3 = new Genre(); g1.Name ="Hip Hop"; g2.Name ="Rock"; g3.Name ="Country"; Console.WriteLine ("Genres: {0}, {1}, {2}", g1.Name, g2.Name, g3.Name); } } |
输出:
1 | "Genres: Hip Hop, Rock, Country" |
这些是自动属性
基本上是用支持字段编写属性的另一种方法。
1 2 3 4 5 6 7 8 9 10 | public class Genre { private string _name; public string Name { get => _name; set => _name = value; } } |
这是实现这一目标的捷径:
1 2 3 4 5 6 7 8 9 10 | public class Genre { private string _name; public string Name { get => _name; set => _name = value; } } |
它是将数据成员公开为公共的快捷方式,这样您就不需要显式地创建私有数据成员。C将为您创建一个私有数据成员。
您可以在不使用此快捷方式的情况下公开数据成员,但如果您决定将数据成员的实现更改为具有某些逻辑,则需要中断接口。所以简而言之,这是创建更灵活代码的捷径。
基本上,这是一个捷径:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Genre{ private string genre; public string getGenre() { return this.genre; } public void setGenre(string theGenre) { this.genre = theGenre; } } //In Main method genre g1 = new Genre(); g1.setGenre("Female"); g1.getGenre(); //Female |
它是C_的自动实现属性。
这是自动实现的属性。这基本上是在C中为类创建属性的一种简略方法,而不必为它们定义私有变量。当获取或设置变量值时不需要额外的逻辑时,通常使用它们。
您可以阅读更多关于msdn的自动实现属性编程指南。
它们是公共属性名称的访问器。
您将使用它们来获取/设置流派实例中该属性的值。
这意味着,如果创建一个类型为tyre的变量,则可以将该变量作为属性访问
1 2 |
get/set模式提供了一种结构,允许在实例化类的属性实例的设置("set")或检索("get")期间添加逻辑,这在属性需要某些实例化逻辑时非常有用。
属性只能有"get"访问器,这样做是为了使该属性为只读
在实现get/set模式时,中间变量被用作一个容器,其中可以放置一个值并提取一个值。中间变量通常以下划线作为前缀。此中间变量是私有的,以确保只能通过其get/set调用访问它。请参阅Brandon的答案,因为他的答案演示了实现get/set最常用的语法约定。
在Visual Studio中,如果在类中定义一个属性
通过向
此外,在Visual Studio 2013和更高版本中,通过添加
这种
必须使用Visual C 2008/CSC v3.5或更高版本进行编译。但您可以编译目标为.NET Framework 2.0的输出(不需要运行时或类来支持此功能)。
get set是属性的访问修饰符。get读取属性字段。set设置属性值。get就像只读访问。设置类似于只写访问。要将属性用作读写,必须同时使用get和set。
基本上是个速记。您可以编写公共字符串名称get;set;,类似于许多示例,但也可以编写它:
1 2 3 4 5 6 7 | private string _name; public string Name { get { return _name; } set { _name = value ; } // value is a special keyword here } |
为什么要使用它?它可以用来过滤对属性的访问,例如,您不希望名称中包含数字。
让我举个例子:
1 2 3 4 5 6 7 8 9 10 | private class Person { private int _age; // Person._age = 25; will through an error public int Age{ get { return _age; } // example: Console.WriteLine(Person.Age); set { if ( value >= 0) { _age = value; } // valid example: Person.Age = 25; } } } |
官方称之为自动实现的属性和它阅读(编程指南)的好习惯。我还推荐教程视频C属性:为什么使用"get"和"set"。
当属性出现在右侧(rhs)时调用get当属性出现在左侧(lhs)时调用set"="符号
对于自动实现的属性,支持字段在场景后面工作,不可见。
例子:
1 | public string Log { get; set; } |
而对于非自动实现的属性,支持字段是预先的,可以作为私有范围变量看到。
例子:
1 2 3 4 5 6 7 | private string log; public string Log { get => log; set => log = value; } |
另外,这里值得注意的是"getter"和"setter"可以使用不同的"backing field"。