dotnet使用误区<初始化类的问题>

在dotnet 3.0后提供了自动属性和初始化器的功能。

自动属性如下2-4行,为什么如此简洁,据了解是因为C#编译器遇上象上面这样的空的get/set属性的话,它会自动为我们在类中生成一个私有成员变量,对这个变量实现一个公开的getter 和setter。

初始化器如下第5行,即可以通过属性或则声明为public的成员变量来初始化一个类。

View Code
1 publicclass Person {
2 publicstring FirstName { get; set; }
3 publicstring LastName { get; set; }
4 publicint Age { get; set; }
5 Person person =new Person { FirstName="Scott", LastName="Guthrie", Age=32 };
6 }

这些确实带来了一些便利之处。

当我们为这些新特性带来的便利感到兴奋时,这其中隐含的陷阱也就悄然浮现。

那么,'初始化器'new出来的类也应该与'构造函数'new出来的类同等吧,事实却泼了我一盆冷水。

初始化器与构造函数在初始化类时所达到的效果并不完全相同。

请看代码:

publicclass FileInfo
{
publicstaticevent EventHandler<ProgressValueArgs> OnProgressValueChanged;
privatelong offset;

public FileInfo()
{
}
public FileInfo(long offset, long size)
{
this.offset = offset;
this.Size = size;
}

publiclong Offset
{
get
{
return offset;
}
set
{
//当offset被赋值时将会引发事件,事件将会把该类本身作为参数传递给事件的接收者
if (null!= OnProgressValueChanged)
OnProgressValueChanged(
this, new ProgressValueArgs(this));

offset
= value;
}
}

publiclong Size
{
get;
set;
}
}

当分别使用对象初始化器赋值方式一、,结果却不同

 1 public class Class1{
2
3      public Class1
4 {
5       //对象初始化器赋值方式一
6 FileInfo fileinfo =new FileInfo(){Offset=-1,Size=-2};
7       //对象初始化器赋值方式二
8       fileinfo = new FileInfo(){Size=-2,Offset=-1};
9 FileInfo.OnProgressValueChanged +=new EventHandler<ProgressValueArgs>(Download_OnProgressValueChanged);
10 }
11
12      privatevoid Download_OnProgressValueChanged(object sender, ProgressValueArgs e)
13 {
14 System.Console.WriteLine(String.Format("OFFSET:{0}大小{1}", e.FileInfo.Id, e.FileInfo.Offset, e.FileInfo.Size));
15 }
16 }

上述情况的原因很简单 ,第一种赋值方式中,事件是在Offset被赋值后就发生了,并在Size被赋值前事件就已经结束。第二种赋值方式中,事件是在Size,Offset都赋值后才发生的,所以产生的结果也就不同。

正确的代码如下:

publicclass FileInfo
{
publicstaticevent EventHandler<ProgressValueArgs> OnProgressValueChanged;
privatelong offset;

public FileInfo()
{
}
public FileInfo(long offset, long size)
{
this.offset = offset;
this.Size = size;
}
publiclong Offset
{
get
{
return offset;
}
set
{
//当offset被赋值时将会引发事件,事件将会把该类本身作为参数传递给事件的接收者
if ( null!= OnProgressValueChanged && true == isSizeChanged ){
OnProgressValueChanged(
this, new ProgressValueArgs(this));
                        isSizeChanged = false;
                                      }

offset
= value;
}
}
private long size;
   private bool isSizeChanged;

publiclong Size
{
get{return size;}
set{
        size = value;
        isSizeChanged = true;
        }        
        }               
}

也就是为事件所依赖的其余变量设立一个标志,这些标志应该作为事件是否被引发的条件。

原文地址:https://www.cnblogs.com/tao_/p/2121374.html