青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

C++ Programmer's Cookbook

{C++ 基礎} {C++ 高級} {C#界面,C++核心算法} {設計模式} {C#基礎}

c#運算符重載和技巧 (equal()函數的實現使用)

Overview

Occasionally this question pops up in newsgroups and forums : Why does C# insist on operator overloads being static? The person raising the question also usually complains how this prevents him or her from implementing virtual overloaded operators.

This article explains why operator overloads have to be static in C# (or any other MSIL compiler), and also shows how you can simulate virtual overloaded operators very easily. It's not a universe-shattering theory (nor a very original one for that matter) and uses a very simple pattern though it's this very simplicity that makes it interesting.

So, why do they have to be static?

In C#, GC'd objects are heap-allocated (the managed CLR heap, not the CRT heap) and thus GC'd objects are always used as references (into the CLR heap). You cannot have stack-based GC'd objects in C# and what this means that you never know when an object variable is null. So, you can imagine what happens if operator overloads were instance methods and you tried to use an operator on a null object! Traditional C++ (as opposed to the CLI version) never faced this problem because the operators were always applied on stack objects; and if at all pointers were used, since pointers followed their own set of operational behavior - you never face a situation where an overloaded op-overload method is invoked on an invalid object.

Traditional C++ example

See below some C++ code that uses virtual operator overloads :-

class Base
{
public:
    Base(int x):x_value(x){}
    virtual bool operator ==(const Base& b)
    {
        return x_value == b.x_value;
    }
protected:
    int x_value;
};

class Derived : public Base
{
public:
    Derived(int x, int y): Base(x), y_value(y){}    
    virtual bool operator ==(const Base& b)
    {        
        Derived* pD = (Derived*)&b;
        return (pD->y_value == y_value) && (pD->x_value == x_value);
    }
private:
    int y_value;
};

int _tmain(int argc, _TCHAR* argv[])
{
    Base* b1 = new Derived(2,11);
    Base* b2 = new Derived(2,11);

    cout << (*b1==*b2) << endl;

    return 0;
}

When (*b1==*b2) is evaluated the == operator overload for class Derived is invoked which can be easily verified by trying out different values for the Base constructors for b1 and b2 or by setting a breakpoint inside the operator overload.

A port to C#

Taking what we know of C# let's attempt a straight-forward port of the above example to C#.

public class Base
{
    int x;

    public Base( int x )
    {
        this.x = x;
    }

    public static bool operator==( Base l, Base r )
    {
        if( object.ReferenceEquals( l, r ) )
            return true;
        else if( object.ReferenceEquals( l, null ) || 
                 object.ReferenceEquals( r, null ) )
            return false;
            
        return l.x == r.x;
    }

    public static bool operator!=( Base l, Base r )
    {
        return !(l == r);
    }

    public int X { get { return x; } }
}

public class Derived : Base
{
    int y;

    public Derived( int x, int y ) : base( x )
    {
        this.y = y;
    }

    public static bool operator==( Derived l, Derived r )
    {
        if( object.ReferenceEquals( l, r ) )
            return true;
        else if( object.ReferenceEquals( l, null ) || 
                 object.ReferenceEquals( r, null ) )
            return false;
        
        return (l.y == r.y) && (l.X == r.X);
    }

    public static bool operator!=( Derived l, Derived r )
    {
        return !(l == r);
    }

    public int Y { get { return y; } }
}

class Program
{
    static void Main()
    {
        Derived d1 = new Derived( 2, 11 );
        Derived d2 = new Derived( 2, 11 );

        Console.WriteLine( d1 == d2 );
        Console.ReadLine();
    }
}

If we run the program as it is above everything will work like the C++ version, but if we introduce a slight change to the program things begin to deviate greatly.

class Program
{
    static void Main()
    {
        Base d1 = new Derived( 2, 11 );
        Base d2 = new Derived( 2, 12 );

        Console.WriteLine( d1 == d2 );
        Console.ReadLine();
    }
}

What's going on here? As simple debugging will show us the despite the objects being compared being instances of the Derived class the Base class == operator is being called. This is because C# (and thus, most other languages) figure out which == operator method to call based on the known (i.e. compile-time) type of the object on the left hand side of the operation.

There are ways around this as you'll see below.

Simulating operator polymorphism with C#

Here, we see how to simulate this in C# :-

class Base
{
    protected int x_value = 0;    

    public Base(int x)
    {
        x_value = x;
    }

    public static bool operator==(Base b1, Base b2)
    {
        if( object.ReferenceEquals( b1, b2 ) )
        {
            return true;
        }
        else if( object.ReferenceEquals( b1, null ) || 
                 object.ReferenceEquals( b2, null ) )
        {
            return false;
        }
        
        return b1.Equals(b2);            
    }

    public static bool operator !=(Base b1, Base b2)
    {
        return !(b1 == b2);
    }

    public override bool Equals(object obj)
    {
        if( obj == null )
            return false;
        
        Base o = obj as Base;
        
        if( o != null )    
            return x_value == o.x_value;
        return false;
    }


    public override int GetHashCode()
    {
        return x_value.GetHashCode();
    }
}

class Derived : Base
{
    protected int y_value = 0;
    

    public Derived(int x, int y) : base(x)
    {
        y_value = y;
    }

    public override bool Equals(object obj)
    {
        if( !base.Equals( obj ) )
          return false; 
          
        Derived o = obj as Derived;
        
        if( o == null )
            return false;
        
        return y_value == o.y_value;
    }

    public override int GetHashCode()
    {
        return x_value.GetHashCode() ^ y_value.GetHashCode() + x_value;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Base b1 = new Derived(10, 12);
        Base b2 = new Derived(10, 11);
        
        Console.WriteLine(b1 == b2);

        b2 = null;

        Console.WriteLine(b1 == b2);

        Console.ReadKey(true);
    }
}

Rather than rely on the == operator overload to do all of the heavy lifting we push all of the work onto the virtual Equals method, from there we let polymorphism work its magic.

Points to note

  • The operator overload has to be static, so we have virtual instance methods that implement the logic for us and we invoke these virtual methods from the static operators

  • In our example, the method Equals corresponds to == and Equals is a virtual method (inherited from System.Object)

  • Within the static overload we need to check for null (to avoid null-reference exceptions)

  • Within each derived class's corresponding operator-logic method (Equals in our case), we cast the System.Object argument to the type of the class (e.g. - In the Derived class we cast to Derived)

  • While Equals and == already exist in System.Object, we can implement similar methods for any operator in our class hierarchies. Say, we need to implement the ++ operator, we then add a PlusPlus (or Increment) virtual method to the root base class in our object hierarchy and in the ++ overload we invoke the Increment method on the passed-in object.

  • In our example, we check for null and return true or false depending on whether the objects are both null or not. But, if you are implementing an operator like ++ then you might want to check for null and throw an ArgumentNullException (to override the inappropriate NullReferenceException that'd otherwise get thrown).

History

  • Apr 19, 2005 : Article first published
  • Apr 20, 2005 : Fixed a bug in Derived.Equals and also changed the GetHashCode implementations for Base and Derived (thanks to Jeffrey Sax for pointing this out)

posted on 2006-03-14 12:35 夢在天涯 閱讀(1987) 評論(0)  編輯 收藏 引用 所屬分類: C#/.NET

公告

EMail:itech001#126.com

導航

統計

  • 隨筆 - 461
  • 文章 - 4
  • 評論 - 746
  • 引用 - 0

常用鏈接

隨筆分類

隨筆檔案

收藏夾

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

積分與排名

  • 積分 - 1811726
  • 排名 - 5

最新評論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
      <noscript id="pjuwb"></noscript>
            <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
              <dd id="pjuwb"></dd>
              <abbr id="pjuwb"></abbr>
              亚洲欧美视频一区二区三区| 亚洲午夜一区二区| 久久九九免费| 欧美中文字幕久久| 亚洲国产精品一区二区第四页av | 亚洲伊人一本大道中文字幕| 欧美制服第一页| 亚洲欧美99| 国产一区二区三区四区| 美女视频黄免费的久久| 欧美成人精品在线播放| 亚洲一区二区三区在线看| 亚洲一区二区三区高清不卡| 国语自产偷拍精品视频偷 | 最新中文字幕亚洲| 一区二区三区日韩精品| 国产欧美日韩精品一区| 欧美激情一区在线| 国产精品伦一区| 久久综合精品国产一区二区三区| 男女av一区三区二区色多| 亚洲视频一二区| 久久精品最新地址| 99视频日韩| 久久er精品视频| 亚洲午夜精品久久| 久久久最新网址| 亚洲欧美电影在线观看| 久久一本综合频道| 午夜在线一区二区| 欧美激情久久久久| 久久久综合精品| 久久嫩草精品久久久久| 欧美日本亚洲| 老司机aⅴ在线精品导航| 欧美日韩专区| 亚洲电影免费观看高清完整版| 欧美视频在线看| 欧美激情第3页| 国产视频在线观看一区二区| 日韩视频在线一区二区| 亚洲国产日韩欧美在线动漫| 亚洲欧美日本精品| 亚洲午夜精品久久| 欧美国产一区二区三区激情无套| 久久久亚洲高清| 国产精品亚洲综合天堂夜夜| 999在线观看精品免费不卡网站| 娇妻被交换粗又大又硬视频欧美| 亚洲一区二区三区四区在线观看| 99国产精品久久久久久久| 久久久人成影片一区二区三区| 欧美一区二区视频网站| 国产精品www994| 99在线|亚洲一区二区| 一本色道久久综合亚洲精品按摩| 鲁大师影院一区二区三区| 久久久人成影片一区二区三区| 国产精品视频免费观看| 在线一区二区三区做爰视频网站| 亚洲美女精品一区| 免费一级欧美片在线播放| 美日韩精品视频免费看| 狠狠噜噜久久| 久久久欧美一区二区| 噜噜噜在线观看免费视频日韩| 国产综合色在线| 久久精品首页| 裸体一区二区| 亚洲国产精品高清久久久| 噜噜噜91成人网| 最近中文字幕日韩精品 | 午夜精品www| 国产精品日韩专区| 亚洲欧美日韩一区| 久久久免费观看视频| 亚洲第一黄色网| 欧美激情亚洲综合一区| 9l国产精品久久久久麻豆| 久久久久天天天天| 欧美成年人视频网站| 亚洲精选一区| 欧美日韩一区二区三区在线观看免| 一级成人国产| 久久久久免费视频| 91久久久久久| 欧美特黄一级大片| 午夜亚洲伦理| 亚洲电影免费观看高清完整版在线观看 | 中国成人亚色综合网站| 国产精品久久二区二区| 久久精品成人欧美大片古装| 欧美国产三级| 亚洲欧美成人| 伊人蜜桃色噜噜激情综合| 欧美黑人在线观看| 亚洲中午字幕| 欧美成人资源网| 亚洲午夜一二三区视频| 国产一区二区三区不卡在线观看| 另类天堂av| 亚洲一区在线视频| 欧美国产精品一区| 午夜激情亚洲| 亚洲欧洲在线视频| 国产精品一区一区| 麻豆9191精品国产| 亚洲欧美国产一区二区三区| 欧美大片一区| 欧美一区二区在线| 亚洲作爱视频| 亚洲成色精品| 国产欧美日本在线| 欧美日韩一区二区三区高清| 亚洲在线免费观看| 在线观看视频一区二区| 国产精品日韩精品| 欧美精品日日鲁夜夜添| 久久精品视频99| 亚洲一区二区三区涩| 亚洲片区在线| 欧美 日韩 国产 一区| 久久er99精品| 亚洲欧美伊人| 亚洲视频一区| 亚洲人体偷拍| 亚洲大片在线| 激情欧美一区二区| 国产日产精品一区二区三区四区的观看方式 | 久久蜜桃av一区精品变态类天堂| 亚洲色图自拍| 亚洲精品资源美女情侣酒店| 黑人极品videos精品欧美裸| 国产伦一区二区三区色一情| 欧美日韩精品一区二区在线播放| 另类欧美日韩国产在线| 久久精品视频va| 欧美伊人久久久久久久久影院| 亚洲天堂网在线观看| 99国产精品99久久久久久| 亚洲激情网站| 亚洲精品日韩久久| 亚洲美女诱惑| 99精品久久久| 在线视频欧美一区| 亚洲一区二区三区777| 亚洲女同同性videoxma| 亚洲一区二区在线播放| 亚洲欧美日韩国产| 久久精品导航| 亚洲欧美视频在线| 欧美尤物巨大精品爽| 久久国产精品久久w女人spa| 欧美一区二区视频网站| 久久久久久一区二区| 另类人畜视频在线| 亚洲国产精品一区二区www| 亚洲欧洲日本mm| 一本色道久久加勒比88综合| 亚洲系列中文字幕| 欧美一区二区三区成人| 久久久亚洲人| 欧美精品久久久久久久久老牛影院| 欧美看片网站| 国产精品亚洲美女av网站| 狠狠入ady亚洲精品经典电影| 亚洲高清av在线| aa级大片欧美| 欧美亚洲专区| 欧美大片91| 中日韩美女免费视频网址在线观看| 亚洲一区在线观看视频| 久久亚洲综合色一区二区三区| 欧美成人资源| 国产精品推荐精品| 在线观看日韩av| 中日韩男男gay无套| 久久成人人人人精品欧| 欧美高清视频一二三区| 在线视频日韩| 久久夜色精品亚洲噜噜国产mv | 亚洲欧美日韩在线不卡| 久久一区二区三区四区| 欧美性做爰毛片| 亚洲电影毛片| 亚洲欧美在线高清| 欧美国产欧美综合| 亚洲综合色网站| 欧美大尺度在线观看| 国产精一区二区三区| 最近中文字幕日韩精品 | 久久综合激情| 亚洲欧美日韩一区二区在线| 欧美大片一区二区| 国内偷自视频区视频综合| 亚洲午夜性刺激影院| 欧美成人免费全部| 久久精品国产亚洲一区二区| 国产精品久久久久77777| 最新国产乱人伦偷精品免费网站 |