1.属性的private set读写器
public int x { get; private set; }
是另一种简写, set前面的private声明是告诉编译器属性X是只读(read-only)的. 意思是对于外部类不能通过属性X给x赋值,而只能读取其值。
例子:
1 public class PswChangingEventArgs : EventArgs 2 { 3 public readonly string message; 4 5 public PswChangingEventArgs(string _message) 6 { 7 this.message = _message; 8 } 9 } 10 11 public class TestClass 12 { 13 public event EventHandler<PswChangingEventArgs> PasswordChanging; // 普通非泛型EventHandler不支持自定义EventArgs 14 15 private string _pwd; 16 public string Pwd 17 { 18 get { return _pwd; } 19 private set 20 { 21 if (string.IsNullOrEmpty(value)) 22 { 23 throw new ArgumentException("password cannot be empty"); 24 } 25 if (_pwd != value) 26 { 27 if (PasswordChanging != null) PasswordChanging(this, new PswChangingEventArgs("password已经改变")); 28 } 29 _pwd = value; 30 } 31 } 32 33 public void Fun() 34 { 35 this._pwd = "abc"; // 直接赋值,什么额外事情都不会发生 36 this.Pwd = "efg"; // 可以引发密码更改事件,可以进行校验 37 } 38 } 39 40 class Program 41 { 42 static void Main(string[] args) 43 { 44 TestClass a = new TestClass(); 45 a.PasswordChanging += new EventHandler<PswChangingEventArgs>(ShowMessage); 46 a.Fun(); 47 //a.Pwd = "1111"; //error,private set:外部不可写入 48 Console.WriteLine("执行Fun()后password:" + a.Pwd); //ok,外部可以读取 49 50 Console.Read(); 51 } 52 53 static void ShowMessage(object sender, PswChangingEventArgs e) 54 { 55 Console.WriteLine("执行Main()里的ShowMessage方法"); 56 Console.WriteLine("sender:"+sender.ToString() + ",message:" + e.message); 57 } 58 }
①.若直接用set,则类外部也可以访问通过Pwd属性读取、写入pwd字段了,扩大了访问权限,破坏了封装、隐蔽性
②.若不用set,则外部只可访问不可写入,但类内部方法虽可读取写入,但写入时不会应发对应操作,不便
③.为了对外隐藏pwd字段的写入(仍可读取),对内可以在写入时设定一些操作。
2.i??操作符:
?? 运算符称为 null 合并运算符,用于定义可以为 null 值的类型和引用类型的默认值。 如果此运算符的左操作数不为 null,则此运算符将返回左操作数;否则返回右操作数。
例子:
1 //int i = null; //error 2 int? i = null; 3 Console.WriteLine(i); 4 int j = i ?? 1; 5 //等价如下: 6 //int j = i.HasValue ? i.Value : 1; 7 Console.WriteLine(i); 8 Console.WriteLine(j);
3.默认参数,例如:
Fun(int a=1),调用时会看到提示Fun([int a=1]),a参数指不指定都合法。
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 TestMethod("Foo"); 6 TestMethod("Foo", "Bar1"); 7 TestMethod("Foo", "Bar1", "Baz1"); 8 9 Console.Read(); 10 } 11 12 static void TestMethod(string foo, string bar = "Bar", string baz = "Baz") 13 { 14 Console.WriteLine("{0, -5} - {1, -5} - {2, -5}", foo, bar, baz); 15 } 16 }
4.readonly 关键字与const 关键字不同。
const 字段只能在该字段的声明中初始化,。 readonly 字段可以在声明或构造函数中初始化。
因此,根据所使用的构造函数,readonly 字段可能具有不同的值。 另外,const 字段为编译时常数,而 readonly 字段可用于运行时常数。
1 public class Test 2 { 3 public readonly string ConnectionString = "User ID=bbb;Password=aaa;Persist Security Info=True;Initial Catalog=xxx"; //声明时赋值 4 public readonly string DatasourceName; //声明但不赋值 5 6 public const string ErrorMessage = "数据库连接出错"; //只能在声明的时候定义.且在类外部调用时使用方法:Test.ErrorMessage; 7 8 public Test(string _datasourceName, string _connectionString) //构造函数里给readOnly变量赋值。不可给const赋值。 9 { 10 DatasourceName = _datasourceName; 11 ConnectionString = _connectionString; //先执行上文的ConnectionString,再执行这里赋值。所以ConnectionString值将不再是上文的"User ID=bbb;Password=aaa; " 12 } 13 }