简体   繁体   English

什么是{得到; 放; C# 中的语法?

[英]What is the { get; set; } syntax in C#?

I am learning ASP.NET MVC and I can read English documents, but I don't really understand what is happening in this code:我正在学习 ASP.NET MVC,我可以阅读英文文档,但我真的不明白这段代码中发生了什么:

public class Genre
{
    public string Name { get; set; }
}

What does this mean: { get; set; }这是什么意思: { get; set; } { get; set; } { get; set; } ? { get; set; }

It's a so-called auto property, and is essentially a shorthand for the following (similar code will be generated by the compiler):这是一个所谓的 auto 属性,本质上是以下内容的简写(类似的代码将由编译器生成):

private string name;
public string Name
{
    get
    {
        return this.name;
    }
    set
    {
        this.name = value;
    }
}

So as I understand it { get; set; }所以据我所知{ get; set; } { get; set; } { get; set; } is an "auto property" which just like @Klaus and @Brandon said is shorthand for writing a property with a "backing field." { get; set; }是一个“自动属性”,这就像@Klaus和@Brandon说是一个写一个属性速记“支持字段。” So in this case:所以在这种情况下:

public class Genre
{
    private string name; // This is the backing field
    public string Name   // This is your property
    {
        get => name;
        set => name = value;
    }
}

However if you're like me - about an hour or so ago - you don't really understand what properties and accessors are, and you don't have the best understanding of some basic terminologies either.但是,如果您像我一样 - 大约一个小时前 - 您并没有真正理解什么是属性访问器,并且您对一些基本术语也没有最好的理解。 MSDN is a great tool for learning stuff like this but it's not always easy to understand for beginners. MSDN 是学习此类内容的绝佳工具,但对于初学者来说并不总是那么容易理解。 So I'm gonna try to explain this more in-depth here.所以我将尝试在这里更深入地解释这一点。

get and set are accessors , meaning they're able to access data and info in private fields (usually from a backing field ) and usually do so from public properties (as you can see in the above example). getset访问器,这意味着它们能够访问私有字段中的数据和信息(通常来自后备字段),并且通常从公共属性访问(如您在上面的示例中所见)。

There's no denying that the above statement is pretty confusing, so let's go into some examples.不可否认,上面的陈述非常令人困惑,所以让我们来看一些例子。 Let's say this code is referring to genres of music.假设这段代码指的是音乐流派。 So within the class Genre, we're going to want different genres of music.因此,在 Genre 类中,我们将需要不同类型的音乐。 Let's say we want to have 3 genres: Hip Hop, Rock, and Country.假设我们想要 3 种类型:嘻哈、摇滚和乡村。 To do this we would use the name of the Class to create new instances of that class.为此,我们将使用的名称来创建该类的新实例

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)

Now that we've created the instances of the Genre class we can set the genre names using the 'Name' property that was set way up above.现在我们已经创建了 Genre 类的实例,我们可以使用上面设置的“Name”属性来设置流派名称。

public string Name //Again, this is the 'Name' property
{ get; set; } //And this is the shorthand version the process we're doing right now 

We can set the name of 'g1' to Hip Hop by writing the following我们可以通过编写以下内容将 'g1' 的名称设置为 Hip Hop

g1.Name = "Hip Hop";

What's happening here is sort of complex.这里发生的事情有点复杂。 Like I said before, get and set access information from private fields that you otherwise wouldn't be able to access.就像我之前说的那样,从您无法访问的私有字段中getset访问信息。 get can only read information from that private field and return it. get只能从该私有字段读取信息并返回它。 set can only write information in that private field. set只能在该私有字段中写入信息。 But by having a property with both get and set we're able do both of those functions.但是通过同时拥有getset属性,我们可以同时执行这两个功能。 And by writing g1.Name = "Hip Hop";并通过编写g1.Name = "Hip Hop"; we are specifically using the set function from our Name property我们专门使用了 Name 属性中的set函数

set uses an implicit variable called value . set使用一个名为value的隐式变量。 Basically what this means is any time you see "value" within set , it's referring to a variable;基本上这意味着任何时候你在set看到“value”,它指的是一个变量; the "value" variable. “价值”变量。 When we write g1.Name = we're using the = to pass in the value variable which in this case is "Hip Hop" .当我们编写g1.Name =我们使用=传递value变量,在本例中为"Hip Hop" So you can essentially think of it like this:所以你基本上可以这样想:

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"'
    }
}

It's Important to note that the above example isn't actually written in the code.需要注意的是,上面的例子实际上并没有写在代码中。 It's more of a hypothetical code that represents what's going on in the background.它更像是一个假设的代码,代表了后台发生的事情。

So now that we've set the Name of the g1 instance of Genre , I believe we can get the name by writing所以现在我们已经设置Genre的 g1 实例的名称,我相信我们可以通过写来获得名称

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"

and if we ran this we would get "Hip Hop" in our console.如果我们运行它,我们会在控制台中得到"Hip Hop"

So for the purpose of this explanation I'll complete the example with outputs as well所以为了这个解释的目的,我也会用输出来完成这个例子

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);
    }
}

Output:输出:

"Genres: Hip Hop, Rock, Country"

Those are automatic properties这些是自动属性

Basically another way of writing a property with a backing field.基本上是另一种编写带有支持字段的属性的方法。

public class Genre
{
    private string _name;

    public string Name 
    { 
      get => _name;
      set => _name = value;
    }
}

This is the short way of doing this:这是执行此操作的简短方法:

public class Genre
{
    private string _name;

    public string Name
    {
      get => _name;
      set => _name = value;
    }
}

It is a shortcut to expose data members as public so that you don't need to explicitly create a private data members.这是将数据成员公开为公共的快捷方式,这样您就无需显式创建私有数据成员。 C# will creates a private data member for you. C# 将为您创建一个私有数据成员。

You could just make your data members public without using this shortcut but then if you decided to change the implementation of the data member to have some logic then you would need to break the interface.您可以在不使用此快捷方式的情况下公开您的数据成员,但是如果您决定更改数据成员的实现以具有某些逻辑,那么您将需要破坏接口。 So in short it is a shortcut to create more flexible code.所以简而言之,它是创建更灵活代码的捷径。

Basically, it's a shortcut of:基本上,这是一个快捷方式:

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# 的自动实现属性

  • The get/set pattern provides a structure that allows logic to be added during the setting ('set') or retrieval ('get') of a property instance of an instantiated class, which can be useful when some instantiation logic is required for the property. get/set 模式提供了一种结构,允许在实例化类的属性实例的设置 ('set') 或检索 ('get') 期间添加逻辑,这在需要某些实例化逻辑时很有用财产。

  • A property can have a 'get' accessor only, which is done in order to make that property read-only一个属性只能有一个“get”访问器,这样做是为了使该属性只读

  • When implementing a get/set pattern, an intermediate variable is used as a container into which a value can be placed and a value extracted.在实现 get/set 模式时,中间变量用作容器,可以在其中放置值和提取值。 The intermediate variable is usually prefixed with an underscore.中间变量通常以下划线为前缀。 this intermediate variable is private in order to ensure that it can only be accessed via its get/set calls.这个中间变量是私有的,以确保它只能通过它的 get/set 调用访问。 See the answer from Brandon, as his answer demonstrates the most commonly used syntax conventions for implementing get/set.请参阅 Brandon 的回答,因为他的回答展示了实现 get/set 最常用的语法约定。

They are the accessors for the public property Name.它们是公共属性名称的访问器。

You would use them to get/set the value of that property in an instance of Genre.您将使用它们来获取/设置流派实例中该属性的值。

That is an Auto-Implemented Property.那是一个自动实现的属性。 It's basically a shorthand way of creating properties for a class in C#, without having to define private variables for them.它基本上是在 C# 中为类创建属性的一种速记方式,而无需为它们定义私有变量。 They are normally used when no extra logic is required when getting or setting the value of a variable.当获取或设置变量的值时不需要额外的逻辑时,通常会使用它们。

You can read more on MSDN's Auto-Implemented Properties Programming Guide .您可以在 MSDN 的Auto-Implemented Properties Programming Guide上阅读更多内容。

In the Visual Studio, if you define a property X in a class and you want to use this class only as a type, after building your project you will get a warning that says "Field X is never assigned to, and will always has its default value" .在 Visual Studio 中,如果您在一个类中定义了一个属性X并且您只想将这个类用作一个类型,那么在构建您的项目之后,您将收到一条警告,指出“字段 X 从未分配给,并且始终具有其默认值”

By adding a { get; set; }通过添加{ get; set; } { get; set; } { get; set; } to X property, you will not get this warning. { get; set; }X的财产,你不会得到这个警告。

In addition in Visual Studio 2013 and upper versions, by adding { get; set; }另外在 Visual Studio 2013 及更高版本中,通过添加{ get; set; } { get; set; } { get; set; } you are able to see all references to that property. { get; set; }您可以看到该属性的所有引用。

在此处输入图片说明

This mean that if you create a variable of type Genre, you will be able to access the variable as a property这意味着如果您创建类型为 Genre 的变量,您将能够将该变量作为属性访问

Genre oG = new Genre();
oG.Name = "Test";

Such { get; set; }这样{ get; set; } { get; set; } { get; set; } syntax is called automatic properties, C# 3.0 syntax { get; set; }语法称为自动属性,C# 3.0 语法

You must use Visual C# 2008 / csc v3.5 or above to compile.您必须使用 Visual C# 2008 / csc v3.5 或更高版本进行编译。 But you can compile output that targets as low as .NET Framework 2.0 (no runtime or classes required to support this feature).但是您可以编译目标低至 .NET Framework 2.0(不需要运行时或类来支持此功能)的输出。

Its basically a shorthand.它基本上是一个速记。 You can write public string Name { get; set; }你可以写public string Name { get; set; } public string Name { get; set; } public string Name { get; set; } like in many examples, but you can also write it: public string Name { get; set; }像很多例子,但是你也可以写:

private string _name;

public string Name
{
    get { return _name; }
    set { _name = value ; } // value is a special keyword here
}

Why it is used?为什么使用它? It can be used to filter access to a property, for example you don't want names to include numbers.它可用于过滤对属性的访问,例如您不希望名称包含数字。

Let me give you an example:让我给你举个例子:

private class Person {
    private int _age;  // Person._age = 25; will throw an error
    public int Age{
        get { return _age; }  // example: Console.WriteLine(Person.Age);
        set { 
            if ( value >= 0) {
                _age = value; }  // valid example: Person.Age = 25;
        }
    }
}

Officially its called Auto-Implemented Properties and its good habit to read the ( programming guide ).它的正式名称为 Auto-Implemented Properties 以及阅读( 编程指南)的好习惯。 I would also recommend tutorial video C# Properties: Why use "get" and "set" .我还推荐教程视频C# 属性:为什么使用 "get" 和 "set"

Get set are access modifiers to property. Get set 是属性的访问修饰符。 Get reads the property field. Get 读取属性字段。 Set sets the property value. Set 设置属性值。 Get is like Read-only access. Get 就像只读访问。 Set is like Write-only access.设置就像只写访问。 To use the property as read write both get and set must be used.要将属性用作读写,必须同时使用 get 和 set。

Get is invoked when the property appears on the right-hand side (RHS) Set is invoked when the property appears on the left-hand side (LHS) of '=' symbol当属性出现在右侧 (RHS) 时调用 Get 当属性出现在 '=' 符号的左侧 (LHS) 时调用 Set

For an auto-implemented property, the backing field works behind the scene and not visible.对于自动实现的属性,支持字段在幕后工作并且不可见。

Example:例子:

public string Log { get; set; }

Whereas for a non auto-implemented property the backing field is upfront, visible as a private scoped variable.而对于非自动实现的属性,支持字段是预先显示的,作为私有范围变量可见。

Example:例子:

private string log;

public string Log
{
    get => log;
    set => log = value;
}

Also, it is worth noted here is the 'getter' and 'setter' can use the different 'backing field'另外,这里值得注意的是'getter'和'setter'可以使用不同的'backing field'

A property is a like a layer that separates the private variable from other members of a class.属性就像一个层,它将私有变量与类的其他成员分开。 From outside world it feels like a property is just a field, a property can be accessed using .Property从外部世界感觉就像一个属性只是一个字段,可以使用 .Property 访问一个属性

public class Person
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string FullName => $"{FirstName} {LastName}";
}

public class Person
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string FullName { get { return $"{FirstName} {LastName}"; } }
}

FullName is a Property.全名是一个属性。 The one with arrow is a shortcut.带箭头的是快捷方式。 From outside world, we can access FullName like this:从外部世界,我们可以像这样访问 FullName:

var person = new Person();
Console.WriteLine(person.FullName);

Callers do not care about how you implemented the FullName.调用者不关心您如何实现 FullName。 But inside the class you can change FullName whatever you want.但是在课堂内,您可以随心所欲地更改 FullName。

Check out Microsoft Documentation for more detailed explanation:查看 Microsoft 文档以获得更详细的解释:

https://docs.microsoft.com/en-us/dotnet/csharp/properties https://docs.microsoft.com/en-us/dotnet/csharp/properties

Basically it helps to protect your data.基本上它有助于保护您的数据。 Consider this example without setters and getter and the same one with them.考虑这个没有 setter 和 getter 的例子,它们也是一样的。

Without setters and getters没有 setter 和 getter

Class Student班级学生

using System;
using System.Collections.Generic;
using System.Text;

namespace MyFirstProject
{
    class Student
    {
        public string name;
        public string gender;
        public Student(string cName, string cGender)
        {
            name = cName;
            gender= cGender;
        }

     }
}

In Main在主要

 Student s = new Student("Some name", "Superman"); //Gender is superman, It works but it is meaningless
 Console.WriteLine(s.Gender);

With setters and getters使用 setter 和 getter

using System;
using System.Collections.Generic;
using System.Text;

namespace MyFirstProject
{
    class Student
    {
        public string name;
        private string gender;
        public Student(string cName, string cGender)
        {
            name = cName;
            Gender = cGender;
        }

        public string Gender
        {
            get { return gender; }
            set
            {
                if (value == "Male" || value == "Female" || value == "Other")
                {
                    gender = value;
                }
                else
                {
                    throw new ArgumentException("Invalid value supplied");
                }
            }
        }
    }
}

In Main:在主要:

  Student s = new Student("somename", "Other"); // Here you can set only those three values otherwise it throws ArgumentException.
Console.WriteLine(s.Gender);

Define the Private variables定义私有变量

Inside the Constructor and load the data在构造函数内部并加载数据

I have created Constant and load the data from constant to Selected List class.我创建了 Constant 并将数据从常量加载到 Selected List 类。

public  class GridModel
{
    private IEnumerable<SelectList> selectList;
    private IEnumerable<SelectList> Roles;

    public GridModel()
    {
        selectList = from PageSizes e in Enum.GetValues(typeof(PageSizes))
                       select( new SelectList()
                       {
                           Id = (int)e,
                           Name = e.ToString()
                       });

        Roles= from Userroles e in Enum.GetValues(typeof(Userroles))
               select (new SelectList()
               {
                   Id = (int)e,
                   Name = e.ToString()
               });
    }

  public IEnumerable<SelectList> Pagesizelist { get { return this.selectList; } set { this.selectList = value; } } 
  public IEnumerable<SelectList> RoleList { get { return this.Roles; } set { this.Roles = value; } }
  public IEnumerable<SelectList> StatusList { get; set; }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM