首先,我要解释的不是用属性封装字段来确保字段值正确,而是很单纯的,将如下代码:
public class MyClass
{
public string Text;
}
修改为:
public class MyClass
{
public string Text { get; set; }
}
没有添加任何的逻辑,只是要求:使用属性替换公共字段。
关于这个问题,网上其实能查到很多说法。但都说得太抽象了,所以我想在此另作一番解释。
首先我们要确认:属性和字段是不同的,不但是在定义、实现的时候不同,使用的时候也是不同的。可能有人要问了,明明语法是完全一样的,即:
var instance = new MyClass();
instance.Text = "Hello world!";
Console.WriteLine(instance.Text);
无论是字段或是属性,都可以使用这样的代码进行调用,且结果是毫无区别的。那么为什么我说是不同的呢?
先创建一个类库,并且将MyClass写到这个类库中。于是两个版本的MyClass可以生成出两个*.dll文件。为了区分,我们将使用字段的称为A、使用属性的称为B。随后创建一个控制台项目C,引用A,将调用的代码写入主方法,编译运行,其会正常输出:
Hello world!
于是我们知道,此*.exe可以正常调用A,那么如果我们直接将B换掉A,会发生什么?(注意不是引用B重新编译,而是直接把*.exe同目录的*.dll换掉)我们可以发现,无法正常运行:
未经处理的异常: System.MissingFieldException: 找不到字段:“MyClassLibrary.MyClass.Text”。
在 MyConsoleApp.Program.Main()
可以发现,它希望找一个字段,而不会去找属性。属性换为字段也同理( 不过出现的异常会是找不到方法)。
所以我们可以知道,对于调用方,字段与属性虽然语法完全一致,但其实编译后结果是不一样的。
那么回到原题,为什么要使用属性呢?
假如你的首个版本只希望储存到内存中,此时你随意可以选择使用属性或是字段。然而谁知道下个版本会发生什么呢?假如你下个版本打算储存到数据库中,那么你将只能使用属性。
在这种情况下,如果你首个版本中使用的是字段,就要发生字段向属性的转变,此时所有的项目都要重新编译。而如果你的类库还允许别人的项目来使用,所有使用你类库的人都需要发布新的版本。
网友评论