سؤال

بعض الكود للسياق:

class a
{

}

class b
{
    public a a{get;set;}
    public static implicit operator a(b b)
    {
        return b.a;
    }
}

  a a=null;
  b b=null;
  a = b;

  //compiler: cannot apply operator '==' to operands of type tralala...
  bool c = a == b; 

هل من الممكن استخدام == المشغل على مثيلات نوع مختلفة، حيث يمكن للمرء تحويل ضمنيا إلى آخر؟ ماذا افتقد؟

يحرر:
إذا كان يجب أن تكون الأنواع هي نفس المكالمات ==، فلماذا

int a=1;
double b=1;
bool c=a==b; 

يعمل؟

هل كانت مفيدة؟

المحلول

ال implicit يعمل المشغل فقط للتخصيص.

تريد زيادة التحميل==) المشغل، على هذا النحو:

class a
{
    public static bool operator ==(a x, b y)
    {
        return x == y.a;
    }

    public static bool operator !=(a x, b y)
    {
        return !(x == y);
    }
}

class b
{
    public a a{get;set;}
    public static implicit operator a(b b)
    {
        return b.a;
    }
}

هذا يجب أن يسمح لك بعد ذلك بمقارنة كائنين من النوع a و b كما اقترح في رسالتك.

var x = new a();
var y = new b();
bool c = (x == y); // compiles

ملحوظة:

أنا أوصي ببساطة تجاوز GetHashCode و Equals الطريقة، حيث يحذر مترجم، ولكن كما يبدو أنك تريد استبقادها، يمكنك القيام بذلك كما يلي.

تغيير إعلان الفصل الخاص بك a ل:

#pragma warning disable 0660, 0661
class a
#pragma warning restore 0660, 0661
{
    // ...
}

نصائح أخرى

هل من الممكن استخدام == المشغل على مثيلات نوع مختلفة، حيث يمكن للمرء تحويل ضمنيا إلى آخر؟

نعم.

ماذا افتقد؟

إليك الجزء ذو الصلة من المواصفات. فاتتك الكلمة المميزة.

يتطلب مشغلو المساواة من نوع المرجع المحدد مسبقا [أن] كلا المعاملتين قيم نوع المرجع أو الفاتح الحرفي. علاوة على ذلك، أ. اساسييوجد تحويل ضمني من نوع المعاملات إلى نوع المعامل الآخر.

التحويل المعرفة من قبل المستخدم هو بحكم التعريف وليس التحويل القياسي. هذه هي أنواع مرجعية. لذلك، فإن مشغل المساواة المحدد مسبقا للمساواة ليس مرشحا.

إذا كانت الأنواع يجب أن تكون نفس المكالمات ==، فلماذا يعمل [Double == Int]؟

افتراضك أن الأنواع يجب أن تكون هي نفسها غير صحيحة. هناك تحويل ضمني معيار من Int To Double، وهناك مشغل للمساواة يتطلب الزوجي، لذلك هذا يعمل.

أعتقد أنك فاتتك أيضا هذا الشيء:

إنه خطأ في وقت الترجمة لاستخدام مشغلي المساواة من نوع المرجع المحدد مسبقا للمقارنة مراجعتين معروفين بأنه مختلف في وقت الترجمة. على سبيل المثال، إذا كانت أنواع الترجمة من الوقت من المعاملات هي نوعان من النوعين A و B، وإذا لم يستمد أي من غيرها من الآخر، فسيكون من المستحيل أن يشير المعاملتين إلى نفس الكائن. وبالتالي، تعتبر العملية خطأ في وقت الترجمة.

وأود أن أتصور أنك بحاجة إلى تجاوز فعلا المشغل == للأنواع التي تهتم بها. سواء كان وقت الترجمة / وقت التشغيل لا يزال يشكو حتى لو كانت الأنواع من القابل للتحويل هو شيء ستحتاج إليه.

public static bool operator ==(a a, b b)
    {
        //Need this check or we can't do obj == null in our Equals implementation
        if (((Object)a) == null)
        {
            return false;
        }
        else
        {
            return a.Equals(b);
        }
    }

بدلا من ذلك، استخدم تطبيقات متساوين مثل Ole6ka يقترح وتأكد من أن التنفيذ يقوم بإلقاء الصب الذي تحتاجه.

http://msdn.microsoft.com/en-us/library/8edha89s.aspx.

في كل حالة، يجب أن تكون المعلمة واحدة هي نفس النوع مثل الفصل أو الهيكل الذي يعلن المشغل (...)

استخدم هذا

 bool c = a.Equals(b);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top