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

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>
              亚洲精品国产欧美| 在线视频亚洲欧美| 久久精品91久久香蕉加勒比 | 国产精品日韩欧美| 亚洲一区二区视频在线观看| 日韩午夜电影在线观看| 欧美视频一二三区| 久久黄色小说| 久久久噜噜噜久久久| 亚洲国产精品久久人人爱蜜臀| 久久亚洲色图| 欧美成人精品一区| 亚洲欧美日韩国产| 久久国产精品99国产| 亚洲电影免费观看高清完整版在线观看 | 久久精品国产精品 | 亚洲国产成人在线视频| 亚洲激情视频在线播放| 欧美性猛交99久久久久99按摩 | 亚洲国产99| 日韩视频精品在线| 国产一区二区三区精品久久久| 久久综合99re88久久爱| 欧美绝品在线观看成人午夜影视 | 亚洲一区精品电影| 午夜欧美视频| 日韩一区二区精品在线观看| 亚洲图片欧洲图片av| 伊人久久噜噜噜躁狠狠躁| 99成人在线| 欲色影视综合吧| 一本色道久久综合亚洲二区三区| 国产女主播一区二区| 欧美风情在线观看| 国产精品美女诱惑| 久久福利精品| 亚洲天堂第二页| 久久琪琪电影院| 午夜精品久久久久久久久久久| 久久夜色精品国产欧美乱| 亚洲伊人观看| 欧美国产精品va在线观看| 久久国产精品一区二区三区| 欧美精品久久99| 麻豆九一精品爱看视频在线观看免费| 欧美视频一区二区在线观看 | 欧美黄色小视频| 国产噜噜噜噜噜久久久久久久久| 欧美激情亚洲综合一区| 国产日韩欧美电影在线观看| 99在线精品观看| 日韩视频第一页| 最新日韩在线| 亚洲精品乱码久久久久久黑人| 久久夜色精品亚洲噜噜国产mv| 亚洲欧美在线高清| 欧美精品在线一区| 欧美xart系列在线观看| 国产三区精品| 亚洲欧美成人精品| 亚洲一区二区在线观看视频| 欧美电影专区| 亚洲福利专区| 最新成人av网站| 久久婷婷av| 美女成人午夜| 亚洲国产高清一区二区三区| 久久九九全国免费精品观看| 久久琪琪电影院| 在线观看日韩国产| 蜜乳av另类精品一区二区| 欧美高清视频在线| 亚洲精品在线免费| 欧美另类人妖| 一区二区欧美日韩| 亚洲免费综合| 国产亚洲制服色| 久久成人免费网| 欧美激情乱人伦| 一二三四社区欧美黄| 欧美视频在线一区| 亚洲欧美激情一区二区| 久久久久综合| 91久久精品国产91久久| 欧美连裤袜在线视频| 一区二区三区黄色| 久久激情久久| 亚洲精品九九| 国产精品成人观看视频免费| 亚洲欧美资源在线| 欧美成人午夜剧场免费观看| 99re热这里只有精品视频| 欧美日韩视频不卡| 亚洲欧美国产精品va在线观看| 蜜桃av噜噜一区二区三区| 亚洲精品中文字幕在线| 国产精品美腿一区在线看| 久久国产精品毛片| 亚洲第一页在线| 性伦欧美刺激片在线观看| 狠狠狠色丁香婷婷综合久久五月| 浪潮色综合久久天堂| 亚洲国产婷婷| 欧美一级视频| 亚洲精品小视频| 久久精品一区蜜桃臀影院| 亚洲国产综合91精品麻豆| 欧美色123| 久久综合九色综合欧美就去吻 | 亚洲永久字幕| 在线电影一区| 国产欧美在线| 欧美日本免费一区二区三区| 久久精品成人一区二区三区| 一二美女精品欧洲| 欧美成熟视频| 久久蜜桃精品| 午夜久久影院| 9人人澡人人爽人人精品| 红桃av永久久久| 国产精品区一区二区三| 欧美激情一区二区三区在线| 欧美一区二区私人影院日本| 一个人看的www久久| 亚洲国产欧美在线| 美国三级日本三级久久99| 欧美一级黄色录像| 国产精品99久久99久久久二8| 亚洲福利av| 国产一区视频在线观看免费| 国产精品v欧美精品v日韩| 欧美日韩成人综合| 欧美精品123区| 嫩模写真一区二区三区三州| 久久精品一二三| 欧美在线不卡| 欧美一级专区| 欧美一级播放| 午夜精品久久99蜜桃的功能介绍| 一区二区三区精品视频在线观看| 亚洲国产第一| 亚洲国产视频一区| 亚洲精品国久久99热| 亚洲国产日韩在线| 亚洲人成7777| 洋洋av久久久久久久一区| 亚洲免费av电影| 日韩一级成人av| 一区二区三区福利| 亚洲香蕉网站| 欧美亚洲视频| 久久夜精品va视频免费观看| 另类亚洲自拍| 欧美大片在线观看| 欧美精品一区二区三区蜜桃| 欧美精品一区在线观看| 欧美日韩色婷婷| 国产精品午夜视频| 国产综合网站| 亚洲福利视频三区| 亚洲乱码国产乱码精品精98午夜 | 亚洲精品精选| 99精品国产一区二区青青牛奶| aa国产精品| 午夜激情久久久| 久久久久国产成人精品亚洲午夜| 久久天堂精品| 亚洲人成欧美中文字幕| 亚洲一区二区在线免费观看视频| 亚洲欧美国产不卡| 麻豆精品一区二区综合av| 欧美激情bt| 国产精品一区免费在线观看| 1024成人网色www| 亚洲图片你懂的| 久久久亚洲影院你懂的| 亚洲福利小视频| 亚洲欧美成人在线| 国产乱码精品一区二区三| 欧美在线一级视频| 久久在线免费观看| 欧美精品www| 国产九九精品视频| 亚洲国产精品国自产拍av秋霞| 在线亚洲免费| 久久性色av| 在线中文字幕一区| 老司机67194精品线观看| 欧美午夜宅男影院| 在线观看欧美日韩国产| 亚洲欧美三级伦理| 欧美激情精品久久久久久大尺度| 亚洲视频福利| 欧美激情精品久久久久| 国产日韩欧美精品一区| 夜夜嗨av一区二区三区网页| 久久亚洲欧美| 亚洲日本一区二区三区| 亚洲欧美在线磁力| 欧美日韩国产另类不卡|