لماذا يمكن أن ترث فئة AC# من واجهة واحدة ضمنيًا وصراحة؟
-
05-07-2019 - |
سؤال
صادف اليوم أن أجد أن فئة C# واحدة يمكن أن ترث واجهة واحدة بطريقة ضمنية وصريحة. هذا يفاجئني. إذا كان C# يعمل بهذه الطريقة ، فيمكن أن يتصرف مثيل واحد بشكل مختلف عند الإشارة إليه بطريقة مختلفة.
interface IFoo
{
void DoSomething();
}
class Foo : IFoo
{
#region IFoo Members
public void DoSomething()
{
Console.WriteLine("do something implicitly");
}
#endregion
#region IFoo Members
void IFoo.DoSomething()
{
Console.WriteLine("do something explicitly");
}
#endregion
}
Foo f = new Foo();
f.DoSomething();
((IFoo)f).DoSomething();
تشغيل الرمز أعلاه والإخراج
do something implicitly
do something explicitly
أعتقد أن هذا التصميم من C# يجعل عدم الاتساق من السلوك. ربما يكون من الضروري أن يرث فئة C# واحدة من واجهة واحدة بطريقة ضمنية أو شرح ، ولكن ليس كلاهما.
هل هناك أي سبب من سبب تصميم C# بهذه الطريقة؟
المحلول
مثالك يفعل ليس تنفيذ IFOO ضمنيًا وصريحًا. يمكنك فقط تنفيذ ifoo.dosometing () بشكل صريح. لديك طريقة جديدة في صفك تسمى dosomething (). لا علاقة له بـ ifoo.dosomething ، إلا أنه يحتوي على نفس الاسم والمعلمات.
نصائح أخرى
كل فئة تنفذ واجهة لها ملف رسم الخرائط بين أعضاء هذا الفصل وأعضاء الواجهة. إذا كان الفصل صراحة ينفذ عضو الواجهة ، ثم ينفذ التنفيذ الصريح دائماً يتم تعيينها إلى الواجهة. إذا لم يكن هناك تطبيق صريح ، فمن المتوقع أن يتم تعيين تطبيق ضمني ، وسيتم تعيين واحد إلى الواجهة.
عندما يكون لدى الفصل نفس اسم العضو والأنواع المرتبطة به كواجهة لكن كما أنه ينفذ بشكل صريح العضو المقابل للواجهة ، ثم التنفيذ "الضمني" للفئة ليس يعتبر تنفيذ الواجهة على الاطلاق (ما لم يطلق عليه التنفيذ الصريح).
بالإضافة إلى معاني مختلفة في كل حالة حيث تنفذ الفصل واجهات متعددة مع نفس اسم/أنواع العضو ، حتى مع وجود واجهة واحدة فقط ، الطبقة نفسها يعتبر أن لديها واجهة ضمنية قد تحتوي على نفس الأعضاء/أنواع الواجهة الوحيدة ولكن لا تزال تعني شيئًا مختلفًا.
هذا يجعلها أكثر مرونة عندما تكون هناك تصادمات. على وجه الخصوص ، انظر إلى IEnumerator
و IEnumerator<T>
- كلاهما لديه Current
خاصية ، ولكن من أنواع مختلفة. أنت لديك لاستخدام تنفيذ الواجهة الصريحة من أجل تنفيذ كل من (والنموذج العام يمتد النموذج غير العام).
الميراث المتعدد: ماذا لو كنت تستمد من واجهتين تحدد نفس الطريقة لأغراض مختلفة؟
interface IMoveable
{
public void Act();
}
interface IRollable
{
public void Act();
}
class Thing : IMoveable, IRollable
{
//TODO Roll/Move code here
void IRollable.Act()
{
Roll();
}
void IMoveable.Act()
{
Move();
}
}
يا رفاق ، شكرا على إجاباتك.
اتضح أن "C# Class يمكن أن يرث واجهة واحدة بطريقة ضمنية وصريحة في نفس الوقت" هو في الواقع وهم. في الواقع ، يمكن لفئة واحدة أن ترث واجهة واحدة لمرة واحدة.
في السؤال الأصلي ، تبدو طريقة "dosomething" "واجهة" IFOO ضمنيًا (يتم إنشاء الطريقة بالفعل بواسطة VS2008) ، لكنها في الواقع ليست كذلك. مع التنفيذ الصريح للواجهة IFOO ، تتحول طريقة "dosomething" إلى طريقة طبيعية لا علاقة لها بـ IFOO إلا بنفس التوقيع.
ما زلت أعتقد أنه تصميم صعب لـ C#، ومن السهل استخدامه عن طريق الخطأ. قل ، لدي بعض الكود مثل هذا
Foo f = new Foo();
f.DoSomething();
الآن ، أريد إعادة تشكيله إلى الكود أدناه. يبدو الأمر جيدًا تمامًا ، لكن نتيجة التنفيذ مختلفة.
Action<IFoo> func = foo => foo.DoSomething();
func(f);