• 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;
            }        
            }               
    }

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

  • 相关阅读:
    rabbitmq-高级(死信队列)
    rabbitmq-高级(TTL过期时间)
    springboot整合rabbitmq(topic主题模式)
    springboot整合rabbitmq(direct路由模式)
    glide图片加载库
    自己封装的OKhttp请求
    手机上搭建微型服务器
    listview实现点击条目上的箭头展开隐藏菜单。
    recycleview + checkbox 实现单选
    recycleview中使用checkbox导致的重复选中问题
  • 原文地址:https://www.cnblogs.com/tao_/p/2121374.html
Copyright © 2020-2023  润新知