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

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看| 亚洲欧美国产一区二区三区| 国产欧美一区二区精品忘忧草| 欧美亚洲一级| 久久精品免视看| 亚洲激情第一区| 亚洲国产婷婷综合在线精品| 欧美 日韩 国产一区二区在线视频 | 欧美伊人久久久久久午夜久久久久| 免费观看久久久4p| 亚洲美女诱惑| 亚洲免费av电影| 国产美女诱惑一区二区| 久久人人看视频| 欧美精彩视频一区二区三区| 亚洲午夜av在线| 欧美在线亚洲一区| 亚洲乱码国产乱码精品精可以看 | 欧美日韩情趣电影| 欧美在线不卡视频| 免费av成人在线| 亚洲免费在线| 久久久久久久久久久久久久一区| 亚洲日本中文字幕| 亚洲你懂的在线视频| 亚洲成色精品| 亚洲欧美国产日韩中文字幕| 亚洲黄色av一区| 亚洲一区二区在线播放| 91久久精品久久国产性色也91| 一本色道久久综合亚洲精品按摩| 国产一区二区三区久久悠悠色av| 亚洲精品免费一二三区| 国产亚洲欧美色| 99精品欧美| 亚洲国产欧美一区| 欧美影院午夜播放| 亚洲香蕉伊综合在人在线视看| 久久精品国产精品亚洲精品| 中国成人亚色综合网站| 久久一二三四| 久久久精品日韩欧美| 欧美日韩午夜在线| 欧美电影免费观看高清| 国产毛片精品国产一区二区三区| 91久久综合| 亚洲欧洲日韩在线| 久久久久在线| 久久理论片午夜琪琪电影网| 欧美午夜剧场| 99在线热播精品免费| 亚洲肉体裸体xxxx137| 久久久午夜视频| 久久婷婷一区| 黑人巨大精品欧美一区二区| 亚洲综合色视频| 午夜精品久久久久久久久| 欧美视频一区二区| 亚洲美女黄色片| 一区二区三区精品| 欧美日韩国产黄| 亚洲人午夜精品免费| 亚洲精品在线二区| 欧美精品情趣视频| 亚洲日本免费| 亚洲一区二区三区久久 | 欧美成人一区在线| 亚洲黄色高清| 在线视频欧美精品| 欧美日韩小视频| 亚洲无线视频| 欧美成人亚洲成人日韩成人| 亚洲大片在线| 日韩一级精品| 欧美肉体xxxx裸体137大胆| 在线亚洲观看| 欧美一区永久视频免费观看| 国产亚洲精品aa午夜观看| 欧美在线免费视频| 蜜月aⅴ免费一区二区三区| 亚洲国产一区二区视频| 欧美精品一区在线观看| 99re66热这里只有精品4| 午夜精品久久久久久久久久久| 国产欧美一区二区精品忘忧草 | 亚洲国产日韩精品| 亚洲一区二区在线播放| 国产精品久久毛片a| 欧美在线一二三区| 亚洲高清精品中出| 亚洲欧美精品在线| 国模 一区 二区 三区| 久久色在线播放| 亚洲免费高清视频| 久久久久综合| 一区二区av在线| 国产亚洲精品久久飘花| 免费在线视频一区| 亚洲综合日韩中文字幕v在线| 猛干欧美女孩| 中文国产一区| 亚洲国产精品久久91精品| 欧美理论电影网| 久久国产视频网| 一区二区三区精品| 欧美成人性生活| 性高湖久久久久久久久| 91久久精品美女高潮| 国产乱人伦精品一区二区| 欧美 日韩 国产一区二区在线视频 | 午夜精品久久久久久久久久久| 国产欧美精品va在线观看| 久久米奇亚洲| 性欧美在线看片a免费观看| 欧美激情第六页| 久久久久久久一区| 亚洲一二三区在线| 亚洲卡通欧美制服中文| 国产亚洲女人久久久久毛片| 欧美日韩亚洲综合在线| 久久嫩草精品久久久精品| 亚洲午夜一区二区| 亚洲人成在线观看网站高清| 免费一级欧美在线大片| 久久成人一区二区| 亚洲欧美成人| 亚洲一区二区三| 亚洲深夜影院| 在线一区日本视频| 亚洲精品影视| 亚洲精品一二三区| 在线日韩视频| 在线免费一区三区| 国产性色一区二区| 国产日本欧洲亚洲| 国产日本欧美一区二区三区| 国产精品高清免费在线观看| 欧美日韩成人一区| 欧美激情中文字幕一区二区| 午夜精品亚洲一区二区三区嫩草| 夜夜爽99久久国产综合精品女不卡| 亚洲国产精品99久久久久久久久| 极品少妇一区二区| 国一区二区在线观看| 国产在线成人| 激情欧美日韩一区| 在线电影国产精品| 亚洲丁香婷深爱综合| 亚洲第一精品影视| 亚洲国内精品在线| 亚洲区中文字幕| 一本久道久久久| 亚洲精品乱码| 在线视频欧美精品| 亚洲女同在线| 久久婷婷丁香| 欧美 日韩 国产 一区| 欧美激情视频给我| 亚洲风情亚aⅴ在线发布| 日韩视频精品在线| 亚洲一区二区三区777| 午夜精品久久久久影视| 欧美一级成年大片在线观看| 久久天天躁狠狠躁夜夜爽蜜月| 免费成人小视频| 欧美日韩综合在线免费观看| 国产精品入口福利| 亚洲二区在线观看| 亚洲在线观看免费| 久久精品国产清自在天天线| 欧美成人免费播放| 亚洲美女黄色片| 香蕉精品999视频一区二区| 久久躁日日躁aaaaxxxx| 欧美精品一区二区三区在线播放 | 欧美高清在线观看| 99热在这里有精品免费| 午夜精品短视频| 免费试看一区| 国产精品一区二区三区久久| 1024精品一区二区三区| 中文日韩在线视频| 久久久蜜桃精品| 亚洲精品乱码久久久久久黑人| 亚洲欧美日韩国产中文在线| 老司机一区二区三区| 国产精品视频成人| 一区二区三区四区五区精品| 免费日韩成人| 亚洲欧美在线播放| 欧美日韩国产一级片| 一区二区三区在线看| 亚洲欧美在线另类| 亚洲美女电影在线| 欧美国产日本韩| 在线欧美日韩| 久久视频在线视频|