为什么我们需要C#中的属性
你能告诉我C#中属性的确切用法吗?我的意思是实用的解释
在我们的项目中,我们正在使用像
/// /// column order /// protected int m_order; /// /// Get/Set column order /// public int Order { get { return m_order; } set { m_order = value; } } /// /// constructor /// /// column name /// column width /// column order public ViewColumn(string name, int width, int order) { // // TODO: Add constructor logic here // m_name = name; m_width = width; m_order = order; } /// /// returns the column name, width, and order in list view. /// /// string represent of the ViewColumn object public override string ToString() { return (string.Format("column name = {0}, width = {1}, order = {2}.", m_name, m_width, m_order)); } /// /// Do a comparison of 2 ViewColumn object to see if they're identical. /// /// ViewColumn object for comparison /// True if the objects are identical, False otherwise. 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; }
想一想:你有一个房间,你想要管理谁可以进来保持房间的内部一致性和安全性,因为你不希望任何人进来搞乱它并让它像什么都没发生一样。 因此,这个房间将是你的实例化课程,属性将成为人们进入房间的门。 您在物业的设置者和吸气剂中进行适当的检查,以确保任何意外的事情进入和离开。
更多技术答案将是封装,您可以查看此答案以获取更多信息: https : //stackoverflow.com/a/1523556/44852
class Room { public string sectionOne; public string sectionTwo; } Room r = new Room(); r.sectionOne = "enter";
人们很容易进入sectionOne,没有任何检查。
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";
现在你检查了那个人并且知道他是否有邪恶的东西。
简短回答:封装
答案很长:属性非常多才多艺。 它允许您选择将数据公开给外部对象的方式。 设置值时,可以注入一些数据validation。 它还解决了Java等等中出现的getX()
和setX()
方法的难题。
很多原因:
- 语义。 属性将您的类型的实现与接口分开。
- 二进制兼容性。 如果您需要更改属性,则可以在不破坏相关代码的二进制兼容性的情况下执行此操作。 对于字段,即使新实现使用具有相同名称的属性,也必须重新编译所有内容 。
- 数据绑定。 你不能数据绑定到一个字段。
这是一个常见的模式:
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; } } }
简而言之,这允许我们访问Foo实例上的Bar对象。 这种封装意味着我们不必担心如何检索Bar,或者是否已经实例化了foo.bar。 我们可以使用该对象,并让Foo类的内部处理它。
这是使用它的方式,除了你设置它的方式,可能。 您可能希望在类中使用该属性,而不是访问成员变量,因此您可以使用有关每个成员变量的统一规则。 这是使用属性的主要优点,是将访问和设置器逻辑全部集中到一个位置。 这取决于您的具体需求,无论您是否想要使用该属性进行设置。 但请注意,在构造函数中,您在调用Property时要非常小心,因为您可能会或可能不会依赖于正在初始化的类的其他部分,如果通过构造函数访问它们将无法完成。 同样,这取决于您的具体实施。
它使用起来也更清洁:
myObject.Property1 = "Test String"; Console.WriteLine(myObject.Property1);
比你在其他一些语言中看到的:
myObject.setProperty1("Test String"); System.out.writeln(myObject.getProperty1());
这是一个可以封装一些逻辑的情况:
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; } }
他们有用的另一种方式是这样的:
public int Order { get; private set; }
现在你有了一个带有支持成员变量的自动实现的属性,该属性只能在类中设置,但在其他地方读取。
最后,如果您需要控制逻辑,可以这样写:
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... } }
正如Justin所说,封装是OOP的基本原则之一。 您可能希望将类中的数据的内部表示从外部隐藏起来,并提供经过批准的查看/操作方法。
C#属性是提供简单方法的构造。 在你的例子中,你没有在get
和set
方法中做任何事情,但在现实生活中你可能需要做某些事情
- 将货币存储在十分之一美分中作为一个长整数,但作为带有2个小数空格和$符号的字符串返回外部世界。
- 将某个属性限制为只读(甚至只写:对于ex:,密码validation器/散列生成器类)。
- 设置/获取此值时,以某种方式更改对象的状态。
在Java中,您编写的getter和setter是分别返回或接受值的普通方法。
属性用于限制对类的成员变量的直接访问。 使用属性维护抽象。 每当您想要实例化一个对象并使用属性将数据设置为它的成员变量时,您可以检查某些条件是否将该值设置为成员变量。 您可以限制对属性的读写,以便在访问该类的对象时,可以只读取成员变量的值。
设计时间的好处
属性使视觉设计变得简单,您可以使用Visual Studio的最着名的属性浏览器来更改对象的属性。
属性还提供了额外的validation元数据,属性浏览器中的视觉外观,如下拉列表,范围,颜色选择器等。
单独的数据和操作
它们真实地表示对象的“数据”与对象的“动作”(方法)之间的差异。
当我们看课时,如果我们有50种方法可供查看,并不是每个人都会使用正确的函数命名,这将使以后难以理解。 我总是告诉程序员,无论何时编程,都要以这样的方式编写代码:5年后,如果其他人查看代码,他应该理解代码。
使用数据访问的方法名称和一些操作会在长时间内产生混淆…就像Stack一样,Push / Pop是动作但“Size”或“Count”是数据。
创建“Count”属性只是将其目的区分为数据而不是动作。
数据绑定
正如其他人所提到的,属性提供了高级数据绑定,如双向绑定等。
访问限制
您可以拥有其他人提到的只读属性和其他访问者。
reflection
在基于reflection编写通用代码的情况下,使用属性很容易。
不同的存储实施
公共变量仅将数据存储为成员,其他属性提供了以不同forms存储数据的各种方式,例如internaly它们可以存储为哈希表(因为它们在WPF中的依赖项对象中完成)。 它们可以缓存。 它们可以进一步转发给其他一些子实体或外围实体。 但是,对于呼叫者隐藏了实现。
validation
设置属性可能需要某些validation,代码“Set”部分中的validation代码可以轻松帮助您validation输入并相应地报告错误。
通知
设置方法的一部分可以引发通知事件,例如其他对象可以监听的INotifyPropertyChanged.PropertyChanged并更新显示值。 这是高级数据绑定的重要部分。
简而言之,它是一个新的“标准”数据存储,具有先进的设施,然后只是将数据存储在类成员中。 通过避免属性,您通常可以执行所有function,但由于实现可能因人而异,因此它的标准可帮助每个人在一个名为“Properties”的表单中定义/访问/validation/通知数据存储