هل تعتقد أن "السيارات واجهة تنفيذ" ستكون مفيدة في .NET / C# [مغلقة]

StackOverflow https://stackoverflow.com/questions/656564

سؤال

النظر في هذا:

public class interface Person : IPerson
{
  int ID { get; protected set; }
  string FirstName { get; set; }
  string LastName { get; set; }
  string FullName { get { return FirstName + " " + LastName; } }
}

و هذا:

public class StubPerson : IPerson
{
    int ID { get { return 0; protected set { } }
    string FirstName { get { return "Test" } set { } }
    string LastName { get { return "User" } set { } }
    string FullName { get { return FirstName + " " + LastName; } }
}

الاستخدام:

IPerson iperson = new Person();

أو:

IPerson ipersonStub = new StubPerson();

أو:

IPerson ipersonMock = mocks.CreateMock<IPerson>();

حتى في الواقع نحن معلنا IPerson واجهة الشخص الدرجة في نفس الوقت:

public class interface Person : IPerson

هل تعتقد أنه سيكون من المفيد الحصول على هذا النوع من الدعم .NET/C# ؟

تحرير:

بسبب الارتباك الشامل أعتقد أنني بحاجة إلى توضيح المقترحة الغرض:

دون هذه الميزة يتوجب عليك كتابة:

interface IPerson
{
  int ID { get; }
  string FirstName { get; set; }
  string LastName { get; set; }
  string FullName { get; }
}

وكذلك هذا:

public class Person : IPerson
{
  int ID { get; protected set; }
  string FirstName { get; set; }
  string LastName { get; set; }
  string FullName { get { return FirstName + " " + LastName; } }
}

أنا لا أقترح أي التغيير الدلالي في كل شيء.

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

المحلول

فكرت نفس النوع من الشيء قبل فترة, وخاصة للاستخدام في حالة حيث لديك واحد فقط إنتاج تنفيذ واجهة, ولكن إذا أردت أن تسخر بها للاختبار.في اللحظة التي ينتهي قليلا مثل .ج/.ساعة الملفات من ماض.

أشك في النهاية أن فوائد ذلك تفوق تعقيد إضافي سواء في اللغة ثم قراءة التعليمات البرمجية بعد ذلك.كنت لا تزال مهتمة في رؤية استكشاف أكثر شمولا على الرغم من.حتى ذلك الحين, هناك أشياء أخرى أعلى الطريق على رأس قائمة أولوياتي - دعم أفضل ثبات يجري في الأعلى :)

نصائح أخرى

اسمحوا لي أن نرى إذا أنا أفهم ما تسأل عنه:

لماذا لا نعلن واجهة:

interface IPerson
{
    string Name {get;set;}
    int ID {get;set;}
}

والطبقات التي تنفذ تلك الواجهة سوف ترث خصائص دون الحاجة إلى إعادة يعلن لهم:

class Person : IPerson { } 
//person now has properties Name and ID

السبب لا يمكنك أن تفعل هذا على الرغم من نص الواجهة البرمجية الخاصة بك رمز الفئة هي مشابهة جدا ، فإنها يعني جدا أشياء مختلفة.واجهة يقول ببساطة "منفذة سوف يكون string Name مع جالبة واضعة".هو الصف الذي يقول "عودة حقل خاص عندما حاصل على اسم الاحتجاج." حتى إذا كنت تستخدم السيارات-العقارات اختصار السماح مترجم تنفيذ هذا المنطق فإنه لا يزال المنطق, الذي ينتمي إلى فئة.فقط لأن:

string Name {get;set;}

يبدو نفس في واجهة في الصف ، وهذا لا يعني حتى بعد نفس الشيء.

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

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

حسنا أنا أعتقد أن إجابات أخرى سوف تساعدك على فهم استخدام واجهة المنطق المجرد في مختلف فئات محددة ، وأعتقد أيضا يمكنك إنجاز شيء ما على غرار ما تريد باستخدام إعادة بيع ديون الأدوات المضمنة في مقابل.

تحديد فئة...

public class Person
{
  public int ID { get; protected set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string FullName { get { return FirstName + " " + LastName; } }
}

ثم انقر بزر الماوس الأيمن وحدد ريفاكتور -> استخراج واجهة.

سيؤدي هذا إلى إنشاء ملف منفصل يحتوي على واجهة تعريف الفئة, ثم هل يمكن العفن واجهة وتنفيذ الطبقات وفقا لذلك.

استخراج واجهة:

interface IPerson
{
    string FirstName { get; set; }
    string FullName { get; }
    int ID { get; }
    string LastName { get; set; }
}

أعتقد أنا في عداد المفقودين نقطة ما أنت إنجاز طريق خلط فئة واجهة معا ؟ ما المشكلة هل من حل مع هذا النهج ؟

هذا:

IPerson iperson = new Person();

بالفعل القانونية في C#.

تحرير: للتوضيح - رمز أعلاه هو قانوني نظرا التالية:

interface IPerson { }

class Person : IPerson { }

على الأقل أريد Visual Studio إلى تنفيذ خصائص من واجهة مثل السيارات خصائص إن طلب ذلك.

للأسف هذا الخيار لا يجب أن أتعامل مع عدم تنفيذها استثناء بذرة

لا, لأنك ستضطر إلى فضح كل أعضاء الجمهور من واجهة.محاولة ReSharper, و لا تقلق أبدا حول هذا مرة أخرى.

Resharper يمكن أن توفر هذه الوظيفة ، على سبيل المثال ،

  1. يمكنك كتابة شخص من الدرجة الأولى.
  2. يمكنك استخراج واجهة الخاص بك من قبل سحب الأعضاء إلى IPerson واجهة.

وبالتالي يمكن أن يكون لديك Visual Studio السيارات-توليد تنفيذ بذرة بالنسبة لك.

التحديث

على أي حال, دعونا شرح واجهات الأولى نقلا عن الكود الواردة في السؤال:

public class interface Person : IPerson
{
    int ID { get; protected set; }
    string FirstName { get; set; }
    string LastName { get; set; }
    string FullName { get { return FirstName + " " + LastName; } }
}

عليك أن تفهم أن واجهة ليست فئة مجردة.واجهة هو مجرد عقد, مخطط من نوع ما ، مما يعني أنه سوف اقول كائن ما يمكن توقعه في كائن آخر دون رعاية حقا حول كيفية تنفيذه.

فئة مجردة ، من ناحية أخرى ، يمكن أن تحتوي على قصاصات من الوظائف التي يمكن أن تكون موروثة و تجاوزها.

في الحالة المذكورة أعلاه, "واجهة" غير صالح لأن:

  • لم تستطع أن تعلن نطاق القيود على واجهات (العامة والخاصة وحمايتها الداخلية) كما هو تنفيذ التفاصيل
  • أنت لم يعلن الافتراضي التنفيذ (على سبيل المثال ، FullName الملكية) لأن مرة أخرى, هذا هو تنفيذ التفاصيل

يبدو لي ما كنت حقا تريد حقا هي فئة مجردة ، على سبيل المثال ،

public abstract class BasePerson
{
    public abstract int ID { get; protected set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public virtual string FullName { get { return FirstName + " " + LastName; } } 
}

أنا فقط أخمن ولكن ربما هذا هو ما كنت حقا بحاجة.

تحديث 2

حسنا, أعتقد أنا على الحصول على ما تريد أن يحدث إذا ما كنت تريد أن تكون قادرة على كتابة هذا:

public interface IPerson
{
    int ID { get; set; }
    string FirstName { get; set; }
    string LastName { get; set; }
    string FullName { get; }
}

ثم التطبيق الخاص بك تحتاج فقط إلى كتابة هذا:

public class Person : IPerson
{
    public int ID { get; protected set; }
    public string FullName { get { return FirstName + " " + LastName; } } 
}

دون الحاجة إلى تحديد الاسم الأول و اسم العائلة خصائص.

أولا المشكلة التي نحن بحاجة لمعالجة هو حقيقة أن واجهات لا تسمح بالوصول المحددات في تنفيذه:ما سيحدث هو أن خصائص سيرث الوصول الافتراضية محدد ، وهو أمر خاص.

الثاني هو حقيقة أنه في حين أن في أعيننا string FirstName { get; set; } في واجهة ، public string FirstName { get; set; } في الصف نفسه ، هم في الواقع لا:

  • في واجهة العقار التعريف يشير إلى أن طريقة توقيعات جالبة و/أو أساليب اضع سوف تكون متاحة لجميع فئات تنفيذ تلك الواجهة.
  • في فئة الإقامة التعريف إرشاد CLR لإنشاء الكائن المجهول الذي سوف يعقد قيمة العقار.

فرق دقيق عن مبرمج ، عالمين متباعدين عن المترجم.

وأخيرا عندما تقوم بتحديد أنك تنفيذ واجهة Visual Studio لا أداء synctactic السحر تلقائيا يجعل هذه المنشأة بذرة بالنسبة لك.

أعتقد أن أفضل التجريد على هذه الصفة ، أو كما وصفتها هنا, وهو دور.هذا هو مثل واجهة مع رمز.المثال الخاص بك يمكن أن تكون مشفرة مثل هذا:

public role RPerson { 
  int ID { get; protected set; } 
  string FirstName { get; set; } 
  string LastName { get; set; } 
  string FullName { get { return FirstName + " " + LastName; } } 
} 

public class Person : RPerson { }

public class StubPerson : RPerson { 
    int ID { get { return 0; protected set { } } 
    string FirstName { get { return "Test" } set { } } 
    string LastName { get { return "User" } set { } } 
    string FullName { get { return FirstName + " " + LastName; } } 
} 

// ...

RPerson rperson = new Person(); 

RPerson rpersonStub = new StubPerson(); 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top