• .net 知识补充 注意点


    一.关于装箱与拆箱

    看这两篇文章

    http://www.cnblogs.com/mqsuper/archive/2008/08/12/1265520.html

    http://www.cnblogs.com/wjiang/archive/2010/12/29/1920474.html

    需要注意的点

    1. 尽量使用泛型集合
    2. 方法传参数时注意数据类型,减少装箱次数
    3. 结构体需要整体替换改变,内部属性改变无效
    4. 不要使用值类型和字符串相加(以前这被认为是一个技巧),会导致装箱

    二.对象的相等性和同一性

    int a = 1;
    int b = 1;
    Console.WriteLine(a.Equals(b));
    Console.WriteLine(ReferenceEquals(a, b));

    对象的Equals方法可以重写,所以无法得知相等性,ReferenceEquals则比较引用地址

    image

    有没发现ReferenceEquals使得值类型又装箱了

    ==与!=通常会调用内部的Equals方法

    三.Dispose模式

    参考此篇文章

    http://www.cnblogs.com/wing011203/archive/2010/01/14/1648176.html

    即为了防止用户忘记手动释放非托管资源,而在析构函数中释放资源.

    当然也可以手动释放,dispose模式遵照着一定的规则,并没什么奥妙.之前我的理解是如何不通过在析构函数中自动调用Dispose方法,这个想法是错误的.还是通过析构函数中调用Dispose方法.仅仅需要记住其实现的步骤就可以了。

    四.显式隐藏从基类继承的成员

    public class A
    {
        public void Test()
        {
            Console.WriteLine("A");
        }
    }
    
    public class B : A
    {
        new public void Test()
        {
            Console.WriteLine("B");
        }
    }
    
    public class C : B
    {
        new public void Test()
        {
            Console.WriteLine("c");
        }
    }
    
    public static void Main()
    {
        A a = new B();
        a.Test();
        A b = new C();
        b.Test();

    image

    五.常量

    除非确定不会更改,否则不要用常量.常量如静态字段,但不用static关键字,

    public const int aa = 1;

    需要注意的是,若其他程序集使用了这个常量,若重新修改这个常量重新编译,其他程序集也不会起作用,也需要重新编译.

    六.事件引发

    主要在于变量的判定问题。

    版本一.

    public event EventHandler Click;
    
    private void OnClick(EventArgs e)
    {
        if (Click != null) Click(this, e);
    }

    在多线程情景下,Click作为一个公开事件可能在一个线程中事件尚未触发完成,但在另一个线程中则移除了这个事件,就会导致Click事件变为空.所以更正如下

    private void OnClick(EventArgs e)
    {
        var temp = Click;
        if (temp != null) temp(this, e);
    }

    使用内部的一个变量,则可以修正这个错误。

    七.事件的实质

    事件的本质就是委托回调.当定义了一个事件后,编译器会生成相关代码。

    public void add_Click(EventHandler value)
    {
        EventHandler handler2;
        EventHandler click = this.Click;
        do
        {
            handler2 = click;
            EventHandler handler3 = (EventHandler)Delegate.Combine(handler2, value);
            click = Interlocked.CompareExchange<EventHandler>(ref this.Click, handler3, handler2);
        }
        while (click != handler2);
    }
    
    public void remove_Click(EventHandler value)
    {
        EventHandler handler2;
        EventHandler click = this.Click;
        do
        {
            handler2 = click;
            EventHandler handler3 = (EventHandler)Delegate.Remove(handler2, value);
            click = Interlocked.CompareExchange<EventHandler>(ref this.Click, handler3, handler2);
        }
        while (click != handler2);
    }

    以上以线程安全的方式来添加和移除一个委托,所以添加事件和注销事件就是对委托的操作。

    八.显示的事件实现

    若不使用.net内置的事件语法,可以直接通过操作委托来实现一套事件管理机制.

    可以参考上述事件的实现方式,将委托存在Dictionary中.具体参考CLR VIA C#(第3版)

  • 相关阅读:
    LeetCode(65):有效数字
    LeetCode(64):最小路径和
    物理Data Guard的日常维护
    Oracle Data Guard的配置
    SQL基础--完整性约束
    使用rman迁移数据库到异机
    Oracle的表空间和数据文件
    Oracle的控制文件
    Oracle重做日志文件
    RMAN的恢复篇
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/1952504.html
Copyright © 2020-2023  润新知