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

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

搜索

  •  

積分與排名

  • 積分 - 1816419
  • 排名 - 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>
              国产精品免费一区二区三区在线观看 | 久久精品伊人| 久久天天躁夜夜躁狠狠躁2022| 久久这里有精品视频| 国产精品九九| 99国产精品99久久久久久粉嫩 | 国内久久视频| 一本久道综合久久精品| 久久久五月天| 亚洲欧美日韩高清| 欧美日韩成人在线播放| 伊人久久综合| 久久超碰97人人做人人爱| 亚洲精品三级| 你懂的一区二区| 国内精品免费在线观看| 欧美aⅴ99久久黑人专区| 亚洲女同同性videoxma| 欧美日韩在线一区| 一本色道久久加勒比88综合| 亚洲免费激情| 国产精品久久久| 久久久综合网| 欧美人成在线视频| 亚洲深夜福利| 夜夜爽www精品| 欧美日韩ab片| 久久久之久亚州精品露出| 欧美成年人视频| 亚洲精品男同| 亚洲三级视频在线观看| 美日韩精品视频免费看| 久久国产夜色精品鲁鲁99| 国产亚洲成av人在线观看导航| 亚洲一区二区免费| 在线亚洲一区二区| 国产精品毛片一区二区三区| 美日韩免费视频| 国产精品毛片a∨一区二区三区|国| 久久躁狠狠躁夜夜爽| 久久综合狠狠综合久久综青草 | 国产在线拍揄自揄视频不卡99| 欧美激情一级片一区二区| 蜜桃久久精品乱码一区二区| 亚洲国产精品免费| 亚洲日本欧美在线| 国产综合色一区二区三区| 亚洲精品一二三| 在线日韩中文字幕| 日韩视频永久免费观看| 在线观看av不卡| 欧美一区在线看| 亚洲大片av| 久久国产高清| 欧美亚洲免费电影| 久久精品女人| 久久精品国产久精国产思思| 久久久久久999| 一级日韩一区在线观看| 麻豆久久婷婷| 欧美黄色一区| 亚洲品质自拍| 亚洲欧美国内爽妇网| 亚洲午夜精品一区二区三区他趣| 你懂的视频欧美| 亚洲激情在线| 国产日韩一区二区| 亚洲欧美日韩在线| 久久精品导航| 国产亚洲精品一区二555| 亚洲欧洲精品一区二区三区不卡 | 中文网丁香综合网| 亚洲一区免费网站| 久久综合给合久久狠狠色| 久热re这里精品视频在线6| 欧美日韩dvd在线观看| 亚洲国产女人aaa毛片在线| 国产精品久久午夜夜伦鲁鲁| 日韩亚洲国产精品| 中文在线不卡视频| 国产精品日本精品| 亚洲精品网址在线观看| 一区二区三区www| 久久国产一二区| 欧美成在线观看| 国产一区二区三区高清| 欧美在线亚洲| 亚洲国产成人精品久久久国产成人一区| 国产日本欧美一区二区三区在线| 亚洲日本中文字幕免费在线不卡| 99re这里只有精品6| 国产精品久久久久av免费| 亚洲欧美另类久久久精品2019| 久久精品国产清高在天天线| 在线观看三级视频欧美| 欧美精品一区二区三| 在线视频欧美精品| 久久久久国产一区二区| 国产欧美日韩精品一区| 久久精品视频在线看| 亚洲高清影视| 午夜欧美大尺度福利影院在线看| 欧美日韩精品综合| 性色av一区二区三区红粉影视| 亚洲欧美日韩电影| 国产精品视频网| 久久视频一区二区| 中文国产一区| 亚洲成色999久久网站| 在线观看亚洲| 国产精品国产精品国产专区不蜜| 久久国产66| 亚洲一区二区三区在线看 | 亚洲国产精品久久91精品| 欧美精品少妇一区二区三区| 亚洲国产一区二区三区青草影视 | 欧美一级专区免费大片| 国产精品青草综合久久久久99| 久久久99久久精品女同性| 亚洲巨乳在线| 欧美成人69av| 久久九九精品| 亚洲欧美www| 99在线视频精品| 亚洲激情成人| 欧美午夜寂寞影院| 亚洲欧美三级伦理| 亚洲美女av网站| 亚洲电影免费观看高清| 久久亚洲不卡| 久久精品国产综合精品| 亚洲欧美日本伦理| 在线一区亚洲| 一本久道久久综合婷婷鲸鱼| 亚洲国产欧美一区二区三区丁香婷| 国产欧美在线播放| 国产精品久久久久aaaa九色| 欧美日韩精品福利| 欧美激情在线观看| 欧美成人在线网站| 嫩草成人www欧美| 欧美gay视频| 美女啪啪无遮挡免费久久网站| 久久爱www| 久久久精品日韩欧美| 欧美一区二区三区精品| 亚洲国产欧美在线| 亚洲国产欧美一区二区三区丁香婷| 女人天堂亚洲aⅴ在线观看| 久久亚裔精品欧美| 欧美不卡一卡二卡免费版| 欧美成人精品影院| 亚洲国产国产亚洲一二三| 亚洲第一精品影视| 亚洲精品国产拍免费91在线| 亚洲激情一区二区三区| 亚洲人成人一区二区在线观看| 亚洲国产美女| 一区二区国产日产| 亚洲国产成人精品久久久国产成人一区 | 国产精品视频你懂的| 国产欧美一区二区精品婷婷| 国产美女搞久久| 欧美日韩一区二区三| 玖玖在线精品| 欧美激情精品久久久久久大尺度| 亚洲欧美综合国产精品一区| 欧美一区二区三区在| 久久蜜臀精品av| 欧美精品国产| 国产日韩亚洲欧美精品| 亚洲黄页一区| 校园春色综合网| 美女黄色成人网| 99精品欧美一区| 久久精品国产99国产精品| 欧美刺激午夜性久久久久久久| 欧美日韩午夜剧场| 国产亚洲精品福利| 亚洲精品资源| 99精品欧美一区| 欧美亚洲视频在线观看| 欧美国产激情二区三区| 亚洲视频一二三| 免费一级欧美在线大片| 国产精品久久久久影院亚瑟| 伊大人香蕉综合8在线视| 亚洲一区在线直播| 亚洲第一主播视频| 新67194成人永久网站| 欧美福利视频| 国语自产偷拍精品视频偷| 狠狠色丁香婷综合久久| 一区二区国产精品| 老司机成人网| 亚洲一区二区三区免费观看| 可以免费看不卡的av网站| 国产乱理伦片在线观看夜一区 | 国产精品狼人久久影院观看方式| 黄色日韩网站视频|