The C# Shorthand getters and setters
C中的setter和getter如何实现封装?我不是新的当谈到这些设定者和吸气剂,我有背景与编程,特别是Java。在爪哇,你使用这样的设定者和吸气剂。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public class Person { private String fName; public void setName(String someName) { fName = someName; } public String getName() { return fName; } } public class Test { public static void main(String[] args) { Person p = new Person(); p.setName("Bob"); System.out.println(p.getName()); } } |
在C中使用速记
1 2 3 | public class Person { public string fName{ get; set;} } |
C速记getter和setter如何实现封装?如何实现C代码与上面的Java代码相同?有什么限制吗?根据我的观察,只有当"fname"设置为public时,我才能使用它,特别是"public string fname get;set;",但当它变为private时,我不能使用它。但是当我将它设置为private时,我不能再使用其他方法访问它。
它们不允许您指定封装行为。它们的作用是允许您指定这是类的公共接口中的属性,而不是字段。
这里的差别在于,在Java中,吸气剂和设置器只是遵循某种约定的方法(GETXXX,SETXXX)。在C中,属性是一流的构造(即使它们基本上是幕后的getter和setter)。因此,C提供了一种简略的方法来说明您以后可能实现封装(例如,向getter或setter添加行为),但您不想破坏类的使用者,因此您将它们声明为预先设置的属性。
在Java中:
1 2 3 4 5 6 7 | public class Foo { private String fooName; public String BarName; public String getFooName() { return fooName; } public String setFooName(String fooName) { this.fooName = fooName; } } |
C中:
1 2 3 4 | public class Foo { public String FooName { get; set; } public String BarName; } |
假设您在另一个引用foo程序集的程序集中定义了一个使用者类fooreader:
1 2 3 4 5 6 7 8 9 10 11 | public class FooReader { public String ReadFoo(Foo foo) { // This returns the Foo **property** return foo.FooName; } public String ReadBar(Foo foo) { // This returns the Bar **field** return foo.BarName; } } |
现在,把foo改成这个不会破坏fooleader:
1 2 3 4 5 | public class Foo { private String _fooName; public String FooName { get { return _fooName.ToUpper(); } set { _fooName = value; } } public String BarName; } |
但是将foo更改为该值将破坏fooreader-您需要重新编译它:
1 2 3 4 5 6 7 8 | public class Foo { private String _fooName; private String _barName; public String FooName { get { return _fooName.ToUpper(); } set { _fooName = value; } } // This breaks FooReader because you changed a field to a property public String BarName { get { return _barName.ToUpper(); } set { _barName = value; } } } |
正如您自己所说,C版是以下内容的简写:
1 2 3 4 5 6 7 | private string _name; public Name { get { return _name; } set { _name = value; } } |
(注意私有字段不可访问,它是由编译器生成的。您的所有访问都将通过属性进行,甚至从类内部进行)
与Java相比,在这里,GETT/SETTER是简单的方法,这种构造被称为C语言中的属性,并且是编译器特性。
在中,c您的Person类中的代码等价物为:
1 2 3 4 5 6 7 | private String _name; public string Name { get { return _name; } set { _name = value; } } |
从C 3开始,可以将其浓缩为:
1 | public string Name { get; set; } |
这是一个自动实现的属性,编译器将自动生成与长时间编写相同的封装代码。将自动为您以及
我将稍微修改您的问题,以便提供更好的比较。在爪哇中,通常有公共吸引子和私有设置器,构造函数是变量的初始化器[SiC],例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class Person{ private String fName; public Person (String name) { setName(name); } private void setName(String someName){ fName = someName; } String getName(){ return fName; } } |
类的用户只能通过构造函数在初始化后检索值:
1 2 3 4 5 6 | public class Example { Person person = new Person("Fred"); System.out.println(person.getName()); // Allowed System.out.println(person.fName); // Not allowed because fName is a local class variable person.setName("Aaron"); // Not allowed because setName() is a local class method } |
现在,这是C可能变得混乱的地方,因为您不使用
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class Person { public String fName {get; private set;} public Person(String name) { this.fName = name; } } public class Example { Person person = new Person("Fred"); Console.WriteLine(person.fName); // This is allowed person.fName ="Tony"; // Not allowed because setter is private } |
现在,如果要使用上述约定向getter和setter添加逻辑,则需要引入局部私有变量,但
1 2 3 4 5 6 7 8 9 10 | class Person { private String _fName; public String fName { get { return _fName +".addedText"; } private set { _fName = value.ToLower(); } } public Person(String fName) { this.fName = fName; } } |
现在,这是否比Java更好或更糟是有争议的,但是从我所看到的,您的代码将不适合在C.Y.如果你做一些类似的东西,虽然语法明智的工作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Person2 { private String fName; public Person2(string fName) { setFname(fName); } private void setFname(String fName) { this.fName = fName.ToLower(); } public String getFname() { return this.fName+".addedText"; } } |