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

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>
              国产精品社区| 国产日产欧美一区| 亚洲欧洲综合另类| 欧美91视频| 麻豆av一区二区三区| 影音先锋在线一区| 欧美成人官网二区| 欧美成人有码| 一区二区三区精品| 亚洲午夜女主播在线直播| 国产精品嫩草99a| 久久久亚洲高清| 久久综合给合| 一本色道久久综合亚洲精品按摩| 亚洲精品午夜| 国产精品视频男人的天堂| 久久精品国产一区二区三区| 久久久在线视频| 夜夜精品视频| 欧美影院精品一区| 亚洲人成亚洲人成在线观看图片 | 亚洲电影在线| 亚洲黑丝在线| 欧美天天在线| 久久嫩草精品久久久久| 女同性一区二区三区人了人一| 亚洲精品在线二区| 性色av一区二区三区红粉影视| 在线不卡视频| 亚洲一级在线| 亚洲国产黄色片| 国产精品99久久久久久白浆小说| 国产在线成人| 99视频在线观看一区三区| 国产综合精品| 日韩视频免费| 樱桃国产成人精品视频| 正在播放亚洲一区| 亚洲精品色图| 久久精品动漫| 亚洲午夜电影网| 老司机免费视频一区二区三区| 午夜精品在线| 欧美日本中文字幕| 欧美成人69av| 国产在线不卡精品| 亚洲一区三区视频在线观看| 日韩一级免费| 免费日本视频一区| 久久综合导航| 国产亚洲一区二区在线观看| 夜夜嗨av一区二区三区网站四季av | 亚洲国产精品成人综合| 国产亚洲精品bv在线观看| 99re6热在线精品视频播放速度| 亚洲成人在线视频播放| 欧美一级在线播放| 亚洲欧美日韩精品久久| 欧美日韩成人在线| 亚洲国产一成人久久精品| 精品88久久久久88久久久| 午夜精品福利电影| 午夜精品视频在线观看| 欧美三级电影网| 99re亚洲国产精品| 9国产精品视频| 欧美精品在欧美一区二区少妇| 欧美国产日韩a欧美在线观看| 在线不卡欧美| 蘑菇福利视频一区播放| 欧美高清视频在线| 亚洲精品少妇网址| 欧美黄色日本| av成人免费| 午夜在线不卡| 国产一区二区精品丝袜| 欧美一区二区视频97| 久久男女视频| 亚洲狠狠婷婷| 欧美日韩伦理在线| 中文国产成人精品久久一| 先锋影院在线亚洲| 国产亚洲va综合人人澡精品| 久久精品观看| 亚洲国产乱码最新视频| 亚洲天堂成人在线观看| 国产精品日本精品| 久久九九热免费视频| 欧美成人小视频| 亚洲深夜福利| 国产日韩在线看片| 噜噜噜噜噜久久久久久91 | 久久久久综合一区二区三区| 国产一区二三区| 毛片基地黄久久久久久天堂| 亚洲人成毛片在线播放| 亚洲一区在线免费观看| 国产一区二区三区观看| 嫩草影视亚洲| 亚洲无线观看| 欧美高清视频一区| 亚洲欧美日韩国产一区二区| 韩国在线视频一区| 欧美日韩国产丝袜另类| 午夜精品久久久久久久男人的天堂| 久久噜噜亚洲综合| 在线一区二区视频| 一区二区三区在线看| 欧美人与性动交cc0o| 西西人体一区二区| 亚洲日本aⅴ片在线观看香蕉| 欧美在线国产| 日韩视频在线一区二区| 国产亚洲va综合人人澡精品| 欧美精品久久一区二区| 欧美一站二站| 亚洲视频播放| 亚洲国产精品久久久久婷婷884| 午夜精品久久久久久久白皮肤| 在线播放精品| 国产乱码精品| 国产精品swag| 欧美福利一区| 久久综合狠狠综合久久综青草 | 亚洲欧美日韩一区在线| 亚洲精品免费一二三区| 另类尿喷潮videofree| 香蕉久久夜色精品国产使用方法 | 欧美日韩精品一区二区天天拍小说 | 久久成人免费网| 亚洲网站视频福利| 亚洲精品久久嫩草网站秘色| 另类尿喷潮videofree| 性欧美暴力猛交69hd| 一区二区三区欧美视频| 亚洲精品免费在线播放| 在线观看91精品国产麻豆| 国产一区二区三区无遮挡| 国产精品人人爽人人做我的可爱| 欧美激情一区二区| 欧美国产日韩二区| 免费成人黄色片| 久热爱精品视频线路一| 久久久国产精品一区二区三区| 午夜欧美电影在线观看| 亚洲少妇自拍| 亚洲欧美高清| 午夜精品久久99蜜桃的功能介绍| 亚洲午夜av| 亚洲欧美日本伦理| 午夜精品免费在线| 亚洲欧美日韩精品久久久| 亚洲一区三区电影在线观看| 亚洲免费在线视频一区 二区| 亚洲视频第一页| 先锋影音久久| 久久噜噜亚洲综合| 美女被久久久| 欧美日韩精品免费观看视一区二区| 欧美国产日本| 欧美亚州一区二区三区| 国产精品视频九色porn| 国产一区二区高清| 亚洲观看高清完整版在线观看| 亚洲欧洲视频在线| 亚洲一区二区精品视频| 欧美一级视频精品观看| 久久一区二区三区四区五区| 欧美成人一区二区三区片免费| 亚洲日本中文字幕免费在线不卡| 亚洲精品在线视频| 亚洲综合国产激情另类一区| 久久精品理论片| 欧美国产精品久久| 国产精品美女999| 国模 一区 二区 三区| 亚洲精选国产| 新67194成人永久网站| 美女久久一区| 99视频+国产日韩欧美| 欧美在线看片| 欧美 日韩 国产在线 | 欧美一区二区三区四区在线| 久久综合精品国产一区二区三区| 欧美日韩第一页| 国产一区二区三区四区三区四| 亚洲精品国久久99热| 午夜精品婷婷| 亚洲国产日韩欧美在线动漫| 亚洲天堂成人在线观看| 老司机精品视频网站| 国产精品久久久久久久app| 激情五月婷婷综合| 亚洲欧美成人网| 欧美黄在线观看| 翔田千里一区二区| 欧美日韩国产天堂| 在线精品一区二区| 久久福利毛片| 亚洲小说欧美另类社区|