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

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)在天涯 閱讀(1987) 評(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

搜索

  •  

積分與排名

  • 積分 - 1811726
  • 排名 - 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>
              亚洲精品影院| 国产精品美女在线| 亚洲欧美日本在线| 一区二区三区高清在线观看| 久久精品人人爽| 在线亚洲电影| 亚洲无玛一区| 欧美一区二区精品久久911| 中文成人激情娱乐网| 亚洲日本激情| 亚洲精品1234| 亚洲视频1区| 欧美在线高清| 免费亚洲一区二区| 欧美日韩成人一区二区| 欧美丝袜一区二区| 国产精品影视天天线| 国产在线一区二区三区四区| 激情成人亚洲| 亚洲视频导航| 欧美sm重口味系列视频在线观看| 欧美风情在线观看| 在线一区二区视频| 蜜臀91精品一区二区三区| 欧美性猛交一区二区三区精品| 国产亚洲福利| 亚洲一区999| 亚洲激情六月丁香| 欧美主播一区二区三区美女 久久精品人| 久久九九免费| 国产日韩精品电影| 亚洲一区二区在线播放| 欧美a级片网| 久久国产欧美日韩精品| 久久精品一级爱片| 亚洲你懂的在线视频| 欧美日韩a区| 久久漫画官网| 亚洲人成人一区二区三区| 亚洲欧美日本国产有色| 欧美www视频| 亚洲国产综合在线看不卡| 久久综合网hezyo| 欧美在线高清| 极品少妇一区二区三区| 久久久www成人免费精品| 亚洲视频每日更新| 国产欧美精品一区aⅴ影院| 午夜精品久久久99热福利| 一道本一区二区| 国产精品嫩草久久久久| 欧美专区日韩专区| 亚洲国产色一区| 亚洲精品一二三区| 欧美成人综合一区| 亚洲一级二级在线| 欧美一区二区播放| 亚洲精品1区2区| 一区二区三区日韩精品视频| 国产精品欧美日韩一区二区| 久久精品欧洲| 欧美午夜激情视频| 欧美成人一品| 国产区在线观看成人精品| 欧美大片一区二区| 国产日产精品一区二区三区四区的观看方式 | 欧美高清不卡| 亚洲欧美在线播放| 欧美精品乱码久久久久久按摩| 亚洲欧美日韩国产另类专区| 鲁大师成人一区二区三区| 亚洲小说欧美另类社区| 狼人天天伊人久久| 麻豆成人av| 精品成人一区二区| 性做久久久久久| 欧美一级免费视频| 国产嫩草影院久久久久| 日韩天天综合| 欧美一区二区三区男人的天堂| 欧美日韩在线精品| 99国产精品国产精品久久| 最新成人av在线| 免费久久99精品国产| 91久久精品www人人做人人爽| 亚洲伦理精品| 国产精品高潮呻吟久久av无限 | 国产欧美在线观看| 亚洲视频碰碰| 久久亚洲精品一区二区| 亚洲电影欧美电影有声小说| 欧美大片va欧美在线播放| 亚洲第一天堂av| 亚洲一区国产精品| 国产在线精品自拍| 欧美激情综合五月色丁香| 一本色道**综合亚洲精品蜜桃冫| 亚洲视频免费在线观看| 国产精自产拍久久久久久| 久久精品99无色码中文字幕| 噜噜噜在线观看免费视频日韩| 亚洲黄色影片| 日韩天堂av| 国产一区久久久| 麻豆精品视频在线| 99精品欧美一区| 国内自拍亚洲| 国产精品一区二区久久久久| 麻豆精品精华液| 欧美专区18| 欧美在线观看视频一区二区| 亚洲国产综合91精品麻豆| 久久看片网站| 另类天堂av| 欧美国产精品一区| 欧美成人免费在线| 欧美 日韩 国产 一区| 亚洲女人小视频在线观看| 夜夜躁日日躁狠狠久久88av| 91久久在线观看| 亚洲国产激情| 亚洲激情av| 国产精品99久久不卡二区| 亚洲国产精品成人一区二区| 伊人精品视频| 亚洲理伦电影| 亚洲欧美日韩另类| 欧美在线观看网站| 久久久国产精品亚洲一区| 久久久久久久综合日本| 美日韩精品视频| 亚洲欧洲一区二区三区久久| 亚洲激情一区| 欧美一级艳片视频免费观看| 久久亚洲一区二区三区四区| 久久一区二区精品| 欧美日韩一区在线播放| 国产精品一页| 99re8这里有精品热视频免费| 亚洲性感美女99在线| 久久久久九九九| 亚洲美洲欧洲综合国产一区| 亚洲欧美日韩精品| 久久一日本道色综合久久| 欧美国产第一页| 欧美一区二区精品| 国产精品入口日韩视频大尺度| 伊甸园精品99久久久久久| 香蕉久久夜色精品国产| 日韩一二在线观看| 欧美日韩国产页| 最新精品在线| 亚洲国产精品久久人人爱蜜臀| 亚洲欧美视频| 国产自产精品| 久久综合电影一区| 欧美一区二区福利在线| 国产乱人伦精品一区二区| 亚洲一区欧美| 亚洲专区免费| 国产三级精品三级| 久久久久国色av免费看影院 | 久久久最新网址| 亚洲欧美激情一区| 国产伦精品一区二区三区照片91 | 久久综合久久综合这里只有精品| 久久久久久噜噜噜久久久精品| 亚洲欧美日韩国产成人精品影院 | 亚洲尤物在线视频观看| 国产精品午夜在线| 久久综合导航| 欧美日韩成人在线| 久久精品国产亚洲一区二区| 久久综合网hezyo| 亚洲网友自拍| 欧美在线亚洲综合一区| 亚洲国产日本| 亚洲在线中文字幕| 亚洲人成网站999久久久综合| 99国内精品久久| 亚洲电影免费| 亚洲一区二区三区777| 亚洲欧美影音先锋| 99热精品在线观看| 久久久久国产精品一区三寸| 夜夜狂射影院欧美极品| 欧美诱惑福利视频| 亚洲免费视频观看| 欧美理论在线| 欧美国产日韩亚洲一区| 国产精品揄拍一区二区| 亚洲人成网在线播放| 亚洲国产精品va在线看黑人| 小辣椒精品导航| 久久精品噜噜噜成人av农村| 国产精品一区一区三区| 亚洲免费影视第一页| 久久久国产91| 亚洲国产欧美日韩精品| 欧美xart系列高清|