(转载自:http://kb.cnblogs.com/page/50502/)
C# get set函数很常用,但是用好还是需要很多经验的,下面的文章就是帮你积累C# get set函数经验的。
C# get set不提倡将域的保护级别设为 public而使用户在类外任意操作--那样太不OO,或者具体点说太不安全!对所有有必要在类外可见的域,C#推荐采用属性来表达。属性不表示存储位置,这是属性和域的根本性的区别。下面是一个典型的属性设计:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace ConsoleApplication1
{
class MyClass
{
private int integer;
public int Integer
{
get { return integer; }
set { integer = value; } // value key word
}
}
class Program
{
public static void Main(string[] args)
{
MyClass MyObject = new MyClass();
Console.WriteLine(MyObject.Integer);
MyObject.Integer++; // 右值为 MyObject.Integer + 1
Console.WriteLine(MyObject.Integer);
Console.ReadKey();
}
}
}
一如我们期待的那样,程序输出0 1。我们可以看到属性通过对方法的包装向程序员提供了一个友好的域成员的存取界面。这里的 value 是 C# get set 的关键字,是我们进行属性操作时的set的隐含参数,也就是我们在执行属性写操作 (set) 时的右值。
属性提供了只读(get),只写(set),读写(get和 set)三种接口操作。对域的这三种操作,我们必须在同一个属性名下声明,而不可以将它们分离,看下面的实现:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace ConsoleApplication1
{
class MyClass
{
private string name;
public string Name
{
<strong>get { return this.name; }</strong>
}
public string Name
{
<strong>set { this.name = value; }</strong> // value key word
}
}
class Program
{
public static void Main(string[] args)
{
MyClass MyObject = new MyClass();
Console.WriteLine(MyObject.Name); // Alert: This member is defined more than once
MyObject.Name = "HelloWorld"; // error
Console.WriteLine(MyObject.Name); // Alert: This member is defined more than once
Console.ReadKey();
}
}
}
上面这种分离Name属性实现的方法是错误的!我们应该像前面的例子一样将他们放在一起。值得注意的是三种属性(只读,只写,读写)被C# get set认为是同一个属性名,看下面的例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace ConsoleApplication1
{
class MyClass
{
protected int num = 0;
public int Num
{
<strong>set
{
num = value;
}</strong>
}
}
class MyClassDerived : MyClass
{
new public int Num // 隐藏基类 Num 属性
{
<strong>get
{
return num;
}</strong>
}
}
class Program
{
public static void Main(string[] args)
{
MyClassDerived MyObject = new MyClassDerived();
// MyObject.Num = 10; // error
((MyClass)MyObject).Num = 10; // 调用基类的 set 属性,右值 value = 1
Console.WriteLine(MyObject.Num);
Console.ReadKey();
}
}
}
由于属性的方法的本质,属性当然也有方法的种种修饰。属性也有5种存取修饰符,但属性的存取修饰往往为public,否则我们也就失去了属性作为类的公共接口的意义。除了方法的多参数带来的方法重载等特性属性不具备外, virtual, sealed, override, abstract等修饰符对属性与方法同样的行为,但由于属性在本质上被实现为两个方法,它的某些行为需要我们注意。看下面的例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace ConsoleApplication1
{
abstract class A
{
private int y;
public virtual int X
{
get
{
return 0;
}
}
public virtual int Y
{
get { return y; }
set { y = value; }
}
public abstract int Z // 自动属性
{
get;
set;
}
}
class B : A
{
private int z;
public override int X
{
get
{
return base.X + 1;
}
}
public override int Y
{
set
{
base.Y = value < 0 ? 0 : value;
}
}
public override int Z
{
get
{
return z;
}
set
{
z = value;
}
}
}
class Program
{
public static void Main(string[] args)
{
B b = new B();
A a = b;
a.Z = 2;
Console.WriteLine( "a.Z : {0}\na.X : {1}", a.Z, a.X );
Console.ReadKey();
}
}
}
这个例子集中地展示了属性在继承上下文中的某些典型行为。这里,类A由于抽象属性Z的存在而必须声明为abstract。子类B中通过base关键字来引用父类A的属性。类B中可以只通过Y-set便覆盖了类A中的虚属性。
自动属性:
使用自动属性,减少代码,代码由编译器提供,我们无需考虑细节
(以下转载自:http://www.jb51.net/article/32406.htm)
public class Product
{
private String name;
public String Name
{
get
{
return name;
}
private set
{
name = value;
}
}
private Decimal price;
public Decimal Price
{
get
{
return price;
}
set
{
price = value;
}
}
public Product(String name, Decimal price)
{
this.price = price;
this.name = name;
}
}
可以改写为:
public class Product
{
public String Name
{
<strong>get;
private set;</strong>
}
public Decimal Price
{
<strong>get;
set;</strong>
}
public Product(String name, Decimal price)
{
Name = name;
Price = price;
}
public override string ToString()
{
return String.Format("{0}:{1}", this.Name, this.Price);
}
}