为什么我们需要 C# 中的属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1523548/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why we need Properties in C#
提问by peter
Can you tell me what is the exact usage of properties in C# i mean practical explanation
你能告诉我 C# 中属性的确切用法是什么吗?我的意思是实用的解释
in our project we are using properties like
在我们的项目中,我们正在使用类似的属性
/// <summary>
/// column order
/// </summary>
protected int m_order;
/// <summary>
/// Get/Set column order
/// </summary>
public int Order
{
get { return m_order; }
set { m_order = value; }
}
/// <summary>
/// constructor
/// </summary>
/// <param name="name">column name</param>
/// <param name="width">column width</param>
/// <param name="order">column order</param>
public ViewColumn(string name, int width, int order)
{
//
// TODO: Add constructor logic here
//
m_name = name;
m_width = width;
m_order = order;
}
/// <summary>
/// returns the column name, width, and order in list view.
/// </summary>
/// <returns>string represent of the ViewColumn object</returns>
public override string ToString()
{
return (string.Format("column name = {0}, width = {1}, order = {2}.",
m_name, m_width, m_order));
}
/// <summary>
/// Do a comparison of 2 ViewColumn object to see if they're identical.
/// </summary>
/// <param name="vc">ViewColumn object for comparison</param>
/// <returns>True if the objects are identical, False otherwise.</returns>
public override bool Equals(object obj)
{
ViewColumn vc = (ViewColumn)obj;
if(m_name == vc.Name &&
m_width == vc.Width &&
m_order == vc.Order)
return true;
else
return false;
}
采纳答案by Tarik
Think about it : You have a room for which you want to regulate who can come in to keep the internal consistency and security of that room as you would not want anyone to come in and mess it up and leave it like nothing happened. So that room would be your instantiated class and properties would be the doors people come use to get into the room. You make proper checks in the setters and getters of your properties to make sure any unexpected things come in and leave.
想一想:您有一个房间,您想对其进行监管,以保持该房间的内部一致性和安全性,因为您不希望任何人进来把它弄乱并让它像什么也没发生一样。所以那个房间将是您的实例化类,而属性将是人们用来进入房间的门。您对属性的 setter 和 getter 进行适当的检查,以确保任何意外的事情进出。
More technical answer would be encapsulation and you can check this answer to get more information on that: https://stackoverflow.com/a/1523556/44852
更多技术答案是封装,您可以查看此答案以获取更多信息:https: //stackoverflow.com/a/1523556/44852
class Room {
public string sectionOne;
public string sectionTwo;
}
Room r = new Room();
r.sectionOne = "enter";
People is getting in to sectionOne pretty easily, there wasn't any checking.
人们很容易进入第一部分,没有任何检查。
class Room
{
private string sectionOne;
private string sectionTwo;
public string SectionOne
{
get
{
return sectionOne;
}
set
{
sectionOne = Check(value);
}
}
}
Room r = new Room();
r.SectionOne = "enter";
now you checked the person and know about whether he has something evil with him.
现在你检查了这个人,知道他是否有什么邪恶的东西。
回答by Justin Niessner
Short answer: Encapsulation
简短回答:封装
Long answer: Properties are very versitile. It allows you to choose how you want to expose your data to outside objects. You can inject some amount of data validation when setting values. It also aliviates the headache of getX()
and setX()
methods seen in the likes of Java, etc.
长答案:属性非常通用。它允许您选择如何向外部对象公开数据。您可以在设置值时注入一些数据验证。它还消除了在 Java 等中看到的令人头疼的方法getX()
和setX()
方法。
回答by jasonh
That's the way to use it, except for the way you're setting it, possibly. Instead of accessing the member variable, you may want to use the property from within the class, so you can use uniform rules regarding each member variable. This is the primary advantage to using properties, is to bring the access and setter logic all into one place. It really depends on your specific needs whether or not you want to set it using the Property or not. Note though, that in the constructor you want to be very careful when calling the Property, as you may or may not be relying on other parts of the class being initialized which would not be done yet if accessed through the constructor. Again, this depends on your specific implementation.
这就是使用它的方式,除了您设置它的方式。您可能希望使用类中的属性,而不是访问成员变量,因此您可以对每个成员变量使用统一规则。这是使用属性的主要优势,是将访问和设置器逻辑都集中在一个地方。无论您是否想使用属性来设置它,这实际上取决于您的特定需求。但是请注意,在构造函数中调用属性时要非常小心,因为您可能会或可能不会依赖正在初始化的类的其他部分,如果通过构造函数访问这些部分还不会完成。同样,这取决于您的具体实现。
It is also a little cleaner to use:
使用起来也更干净一点:
myObject.Property1 = "Test String";
Console.WriteLine(myObject.Property1);
Than what you see in some other languages:
比你在其他一些语言中看到的:
myObject.setProperty1("Test String");
System.out.writeln(myObject.getProperty1());
Here's a case where you can encapsulate some logic:
下面是一个可以封装一些逻辑的案例:
public int Order
{
get { return m_order; }
set
{
// Put some rules checking here. Maybe a call to make sure that the order isn't duplicated or some other error based on your business rules.
m_order = value;
}
}
Another way they're useful would be like this:
他们有用的另一种方式是这样的:
public int Order { get; private set; }
And now you've got an auto-implemented property with backing member variable that can only be set inside the class but read everywhere else.
现在你已经有了一个带有支持成员变量的自动实现的属性,它只能在类中设置,但可以在其他任何地方读取。
Finally, if you need to control the logic, you can write this:
最后,如果需要控制逻辑,可以这样写:
public int Order
{
get { return m_order; }
protected set
{
// Again, you can do some checking here if you want...
m_order = value;
// You can also do other updates if necessary. Perhaps a database update...
}
}
回答by Joel Coehoorn
Lots of reasons:
原因很多:
- Semantics. Properties separate the implementation of your type from the interface.
- Binary Compatibility. If you ever need to change a property, you can do so without breaking binary compatibility for dependent code. With fields, you have to recompile everythingeven if the new implementation uses a property with the same name.
- Databinding. You can't databind to a field.
- 语义。属性将类型的实现与接口分开。
- 二进制兼容性。如果您需要更改属性,您可以在不破坏相关代码的二进制兼容性的情况下这样做。对于字段,即使新实现使用同名属性,您也必须重新编译所有内容。
- 数据绑定。你不能数据绑定到一个字段。
回答by Chetan Sastry
As Justin noted, Encapsulation is one of the basic tenets of OOP. You would want to keep the internal representation of the data in your class hidden from outside and provide approved ways of viewing/manipulating it.
正如 Justin 所指出的,封装是 OOP 的基本原则之一。您可能希望将类中数据的内部表示从外部隐藏起来,并提供经过批准的查看/操作方式。
C# properties are constructs that provide an easy way to do that. In your example, you aren't doing anything inside the get
and set
methods but in real life you may need to do certain things like
C# 属性是提供一种简单方法的结构。在您的示例中,您没有在get
andset
方法内部做任何事情,但在现实生活中您可能需要做某些事情,例如
- Store currency in 10th of cents as a long integer but return to the outside world as a string with 2 decimal spaces and a $ sign.
- Restrict a certain property to be read-only (or even write-only: for ex:, a password validator/hash generator class).
- Change the state of the object somehow when this value is set/get.
- 将货币以 10 美分的形式存储为长整数,但作为带有 2 个小数位和 $ 符号的字符串返回到外部世界。
- 将某个属性限制为只读(甚至只写:例如:密码验证器/哈希生成器类)。
- 在设置/获取此值时以某种方式更改对象的状态。
In Java, you write getters and setters which are plain-old methods that return or accept a value respectively.
在 Java 中,您编写 getter 和 setter,它们是分别返回或接受值的普通方法。
回答by Doug R
Here's a common pattern:
这是一个常见的模式:
class Foo {
private Bar _bar;
//here, Foo has a Bar object. If that object has already been instantiated, return that value. Otherwise, get it from the database.
public Bar bar {
set { _bar = value;}
get {
if (_bar == null) {
_bar = Bar.find_by_foo_name(this._name);
}
return _bar;
}
}
}
In short, this allows us to access the Bar object on our instance of Foo. This encapsulation means we don't have to worry about how Bar is retrieved, or if foo.bar has already been instantiated. We can just use the object and let the internals of the Foo class take care of it.
简而言之,这允许我们访问 Foo 实例上的 Bar 对象。这种封装意味着我们不必担心 Bar 是如何检索的,或者 foo.bar 是否已经被实例化。我们可以只使用该对象并让 Foo 类的内部处理它。
回答by Himadri
Properties are used to restrict direct access to member variables of a class. Abstraction is maintained using properties. Whenever you want to instantiate an object and set data to it's member variables using property you can check some conditions whether the value will be set to the member variable or not. You can restrict read write to a property so that the value of member variable can be readonly, writeonly while accessing the object of that class.
属性用于限制对类成员变量的直接访问。抽象是使用属性来维护的。每当您想实例化一个对象并使用属性将数据设置为它的成员变量时,您可以检查一些条件是否将值设置为成员变量。您可以限制对属性的读写,以便在访问该类的对象时成员变量的值可以是只读的、只写的。
回答by Akash Kava
Design Time Benefits
设计时优势
Properties makes visual designing easy, you have Most Famous Property Browser of Visual Studio to allow you to change properties of object.
属性使可视化设计变得容易,您拥有 Visual Studio 的最着名的属性浏览器,允许您更改对象的属性。
Properties also provide additional metadata of validation, visual appearance inside Property Browser, like drop down, range, color picker etc.
属性还提供额外的验证元数据,属性浏览器内的视觉外观,如下拉、范围、颜色选择器等。
Seperate Data and Actions
分离数据和操作
They truely represent difference between "Data" of object and "Actions" (Methods) of object.
它们真正代表了对象的“数据”和对象的“操作”(方法)之间的区别。
When we look at class, if we have 50 methods to look at, not everyone will always use correct naming of functions, that will make things difficult to understand later on. I always tell the programmers that whenever you program, write the code in such a way that after 5 years, if someone else looks at the code, he should understand the code.
当我们看类时,如果我们有50个方法要看,不是每个人都会使用正确的函数命名,这会导致后面的事情难以理解。我总是告诉程序员,无论何时编程,都要以这样的方式编写代码,即 5 年后,如果其他人看到代码,他应该理解代码。
Using method names of data access and some actions create confusion in long run... like in case of Stack, Push/Pop are actions but "Size" or "Count" is data.
从长远来看,使用数据访问的方法名称和某些操作会造成混淆……例如在堆栈的情况下,推送/弹出是操作,但“大小”或“计数”是数据。
Creating property of "Count" simply distinguishes its purpose as data instead of action.
创建“计数”的属性只是将其目的区分为数据而不是动作。
Databinding
数据绑定
As mentioned by others, properties offer advanced level of databinding like two way binding etc.
正如其他人所提到的,属性提供了高级数据绑定,如双向绑定等。
Access Restrictions
访问限制
You can have readonly properties and additional accessors as mentioned by others.
您可以拥有其他人提到的只读属性和其他访问器。
Reflection
反射
Its little easy to work with properties in case of writing generic code based on reflection.
在基于反射编写通用代码的情况下,使用属性并不容易。
Different Storage Implementation
不同的存储实现
Public variables store data only as members, where else properties provide various ways to store data in different forms like internaly they can be stored as hashtable (as they are done in dependency objects in WPF). They can be cached. They cab be relayed further to some other child entities or foriegn entities. However implementation is hidden for callers.
公共变量仅将数据存储为成员,而其他属性提供了以不同形式存储数据的各种方法,例如在内部它们可以存储为哈希表(就像它们在 WPF 中的依赖对象中完成的那样)。它们可以被缓存。它们可以进一步中继到其他一些子实体或外国实体。然而,调用者的实现是隐藏的。
Validation
验证
Setting property may require certain validation, and validation code in "Set" part of code can easily help you validate the input and report errors accordingly.
设置属性可能需要一定的验证,“设置”部分代码中的验证码可以轻松帮助您验证输入并相应地报告错误。
Notifications
通知
Set part of method can raise notification events such as INotifyPropertyChanged.PropertyChanged which other objects can listen for and update the display value. This is important part of advanced data binding.
方法的 Set 部分可以引发通知事件,例如 INotifyPropertyChanged.PropertyChanged,其他对象可以侦听并更新显示值。这是高级数据绑定的重要部分。
In short, its a new "Standard" of data storage that has advanced facilities then just mere storing the data in the members of class. By avoiding properties typically you can perform all functions, but since implementation may differ from person to person, its a standard which helps everyone to define/access/validate/notify the data storage in one single form called "Properties"
简而言之,它是一种新的数据存储“标准”,具有先进的设施,然后只是将数据存储在类的成员中。通过避免属性,您通常可以执行所有功能,但由于实现可能因人而异,因此它是一种标准,可帮助每个人以一种称为“属性”的单一形式定义/访问/验证/通知数据存储