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

C++ Programmer's Cookbook

{C++ 基礎(chǔ)} {C++ 高級(jí)} {C#界面,C++核心算法} {設(shè)計(jì)模式} {C#基礎(chǔ)}

c#運(yùn)算符重載和技巧 (equal()函數(shù)的實(shí)現(xiàn)使用)

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 夢(mèng)在天涯 閱讀(2013) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C#/.NET

公告

EMail:itech001#126.com

導(dǎo)航

統(tǒng)計(jì)

  • 隨筆 - 461
  • 文章 - 4
  • 評(píng)論 - 746
  • 引用 - 0

常用鏈接

隨筆分類

隨筆檔案

收藏夾

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

積分與排名

  • 積分 - 1818789
  • 排名 - 5

最新評(píng)論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
              老司机精品福利视频| 欧美影院成人| 在线国产日韩| 亚洲欧美国产77777| 亚洲精品视频在线看| 久久漫画官网| 久久久久久午夜| 国产精品一卡二| 一级成人国产| 一区二区三区国产盗摄| 久久影视精品| 久久婷婷色综合| 国产在线精品一区二区夜色| 在线亚洲一区二区| 一区二区日韩精品| 欧美日韩国产页| 亚洲精品乱码久久久久久蜜桃91 | 欧美aa国产视频| 国产日韩欧美制服另类| 亚洲综合电影一区二区三区| 亚洲一区在线直播| 国产精品久久久久91| 一区二区三区精品久久久| 一本色道88久久加勒比精品 | 国产精品九九| 亚洲一区二区三区免费在线观看| 一区二区三区不卡视频在线观看 | 亚洲国产视频一区| 亚洲精品在线观看免费| 欧美激情国产精品| 亚洲精品一区二区三区蜜桃久| 亚洲精品小视频| 欧美精品在线观看播放| 亚洲美女免费视频| 午夜精品视频网站| 国产欧美一级| 久久色中文字幕| 亚洲欧洲综合| 亚洲一区在线直播| 国产亚洲一区精品| 久久综合五月天婷婷伊人| 欧美激情第9页| 亚洲一区二区综合| 国产欧美一区二区精品性| 久久国产一区二区三区| 免费欧美日韩国产三级电影| 亚洲精品日韩激情在线电影| 欧美日韩中国免费专区在线看| 中日韩视频在线观看| 久久久亚洲欧洲日产国码αv | 欧美高清在线视频| 99精品热6080yy久久| 国产精品嫩草影院av蜜臀| 久久九九99| 日韩视频免费大全中文字幕| 久久国产主播精品| 亚洲区第一页| 国产精品视频精品| 久久影院午夜论| 亚洲一级网站| 欧美大片免费观看| 亚洲免费视频一区二区| 亚洲成色777777女色窝| 欧美亚洲第一区| 免费91麻豆精品国产自产在线观看| 日韩特黄影片| 麻豆精品视频| 亚洲永久在线| 亚洲精品一区二区网址| 国产一区激情| 国产精品卡一卡二| 欧美成人午夜激情| 新67194成人永久网站| 亚洲三级色网| 欧美va亚洲va香蕉在线| 先锋影音网一区二区| 亚洲精品一区二区在线观看| 国产真实乱偷精品视频免| 欧美日韩亚洲一区二区| 麻豆freexxxx性91精品| 欧美一区二区国产| 一区二区三区不卡视频在线观看 | 欧美伊人影院| 亚洲一区二区三区四区五区午夜| 欧美国产日韩一区二区| 久久精品国产清高在天天线| 亚洲网站在线观看| 91久久极品少妇xxxxⅹ软件| 国语自产精品视频在线看抢先版结局 | 亚洲国产欧美另类丝袜| 久久久噜噜噜久久人人看| 亚洲欧美日韩精品| 亚洲一区二区三区777| 99re热精品| 亚洲最新在线视频| 亚洲免费观看高清完整版在线观看熊| 精品999成人| 国产一区二区精品| 国产日韩在线一区| 国产女人水真多18毛片18精品视频| 欧美日韩123| 欧美日韩精品在线播放| 欧美高清在线一区| 欧美国产视频在线| 欧美黑人在线播放| 欧美人成在线| 欧美日韩一区二区三区在线看| 欧美激情视频网站| 欧美日本不卡| 欧美三级电影大全| 国产精品婷婷| 国产一区二区三区在线观看免费 | 久久久久久久久久久久久久一区 | 亚洲精品视频在线观看网站| 最新日韩精品| 在线视频亚洲欧美| 亚洲一区二区三区高清| 亚洲欧美日韩另类| 久久精品国产91精品亚洲| 久久精品免视看| 免费观看一区| 91久久在线播放| 亚洲视频免费看| 久久精品av麻豆的观看方式| 久久久久久久一区二区| 欧美成人国产| 国产精品国产三级国产aⅴ9色| 国产精品免费观看在线| 国产一区二区久久精品| 在线播放亚洲| 一区二区三区成人| 欧美在线在线| 欧美激情亚洲视频| 国产精品99久久99久久久二8| 午夜一区二区三区在线观看| 久久久久久久成人| 欧美日韩国产123| 国产视频自拍一区| 亚洲精品日韩精品| 欧美在线观看天堂一区二区三区 | 久久久久久久一区二区三区| 免费观看在线综合| 一本色道久久综合| 久久精品日产第一区二区三区| 欧美国产视频在线观看| 国产精品―色哟哟| 亚洲黄页一区| 欧美影院精品一区| 亚洲国产精品ⅴa在线观看| 亚洲视频在线视频| 久久综合久久综合久久| 国产精品日本一区二区| 亚洲经典一区| 久久精品在线免费观看| 亚洲精品久久久久久久久久久| 午夜精品一区二区在线观看| 欧美jizzhd精品欧美巨大免费| 国产精品一区二区a| 亚洲精品三级| 你懂的视频一区二区| 亚洲伊人伊色伊影伊综合网| 欧美成人精品不卡视频在线观看| 国产欧美精品| 一区二区三区高清在线| 欧美高清在线精品一区| 欧美一区二区在线播放| 国产精品久久久对白| 亚洲毛片在线观看| 欧美成人精品在线播放| 欧美亚洲专区| 国产精品美女www爽爽爽| 日韩视频免费观看高清完整版| 久久亚洲国产精品日日av夜夜| 正在播放亚洲一区| 欧美日韩精品二区| 最新精品在线| 欧美激情视频给我| 久久高清一区| 国产一区二区成人久久免费影院| 亚洲一区二区三区久久| 亚洲区第一页| 欧美刺激午夜性久久久久久久| 伊人久久大香线蕉av超碰演员| 欧美亚洲午夜视频在线观看| 一区二区三区视频观看| 欧美日韩国产精品一区| 99精品热6080yy久久| 亚洲人成人99网站| 欧美电影免费观看高清| 亚洲人成小说网站色在线| 免费亚洲婷婷| 久久亚洲综合| 最新日韩在线| 亚洲大胆女人| 欧美成人在线免费观看| 91久久久久久| 日韩视频在线永久播放| 国产精品大片免费观看| 欧美一级专区| 久久爱另类一区二区小说|