示例代码(替代代码如下),
// person.cs
using System;
class Person
{
private string myName ="N/A";
// Declare a Name property of type string:
public string Name
{
get
{
return myName;
}
set
{
myName = value;
}
}
public override string ToString()
{
return "Name = " + Name;
}
public static void Main()
{
Person person = new Person();
Console.WriteLine("Person details - {0}", person);
person.Name = "Joe";
Console.WriteLine("Person details - {0}", person);
}
}
我们不能直接编写,将myName
从私有更改为公共,不需要声明另一个公共变量Name而不需要使用get和set吗?
替代代码
// person.cs
using System;
class Person
{
public string myName ="N/A";
public override string ToString()
{
return "Name = " + myName;
}
public static void Main()
{
Person person = new Person();
Console.WriteLine("Person details - {0}", person);
person.myName = "Joe";
Console.WriteLine("Person details - {0}", person);
}
}
答案 0 :(得分:15)
外部可见属性优于字段,因为:
属性允许更好的封装。字段是固定的实现,允许消费者直接访问。属性:
松散耦合(因为底层字段可以从变量变为 数据库随时)
允许自定义逻辑(验证,事件通知,延迟加载等)
控制访问(因为逻辑可以在get / set中构建,甚至声明为只读或只写)。
字段不能用于接口。这是测试驱动开发的障碍(首先是接口)。
自动或自动实现的属性既可以像字段一样轻松声明,也可以优化为与字段相同。请参阅here。
声明外部可见字段(public,protected,protected internal)是 FxCop违规。请参阅rule CA1051。
将字段更改为属性是重大更改,因为需要重新编译调用代码(也适用于二进制序列化)。
.NET中的许多库识别 用于XML序列化,WPF绑定,ASP.NET双向绑定等任务,以及Visual Studio设计器。< / p>
答案 1 :(得分:10)
你正在破解OOP的一个基础 - &gt;信息隐藏/封装
通过将您的属性定义为公共属性,您可以为每个人提供对它们的访问权限,并且可以根据需要更改(损坏)它们。这样您就不能保证您的对象始终处于一致状态。
在编程语言中,封装用于表示两个相关但不同的概念之一,有时用于组合[1] [2]:
- 限制访问某些对象组件的语言机制。[3] [4]
- 一种语言结构,有助于将数据与操作该数据的方法(或其他功能)捆绑在一起。[5] [6]一些编程语言研究人员和学者单独使用第一个含义或与第二个结合使用作为面向对象编程的区别特征,而提供词汇闭包的其他编程语言将封装视为与面向对象正交的语言的特征。
第二个定义的动机是,在许多OOP语言中隐藏组件不是自动的或可以被覆盖;因此,信息隐藏被那些喜欢第二种定义的人定义为一个单独的概念。
答案 2 :(得分:0)
在您的示例中,这两种方法之间实际上没有区别。通常,属性使您可以为其他类(使用私有setter)使它们只读 - 您将无法使用该字段执行此类操作。公共领域/财产制定者打破了OOP的封装规则。
答案 3 :(得分:0)
在OOP中,约定是隐藏用户的所有变量,而是使用Getters和Setters来操作它们。在某些情况下,您需要更改变量值,直到保存为止。例如,您提示用户输入一些将是速度的值,用户在MPH中输入值,但您想要转换它们并以Km / h或m / s存储。现在,在这种情况下,setter是有道理的。在某些情况下,您希望将setter或getter设置为private,以使变量只读或只写。但总结一下在OOP公约中,使用setter和getter而不是公共变量。这是封装概念的一部分
答案 4 :(得分:0)
你可以这样做,但不是很好的实践。将私有变量作为一种财产进行入侵意味着您可以更好地控制客户可以做什么和不能做什么
如果它看起来有点冗长,你也可以使用以下
public string Name { get; set; }
答案 5 :(得分:0)
正如bash.d所写,这是OOP的基础。
在这种情况下,我建议将Name放在构造函数中:
class Person
{
public Person(string name)
{
this.myName = name;
}
private string myName ="N/A";
public string Name
{
get
{
return myName;
}
private set
{
myName = value;
}
}
public override string ToString()
{
return "Name = " + Name;
}
public static void Main()
{
Person person = new Person("Joe");
Console.WriteLine("Person details - {0}", person);
Console.WriteLine("Person details - {0}", person);
}
}
其他方法使用方法设置值,是否可以检查处理对象。