طريقة وجود فئة مجردة كمعلمة
-
30-09-2019 - |
سؤال
لديّ فئة A التجريدية ، حيث استخلصت الفئتين B و C. من الفئة A توفر طريقة مجردة DoJob () ، والتي يتم تنفيذها بواسطة كلتا الفئتين المشتقتين.
هناك فئة X التي لديها طرق في الداخل ، والتي تحتاج إلى استدعاء Dojob (). قد لا يحتوي الفئة X على أي رمز مثل B.Dojob () أو C.Dojob ().
مثال:
public class X
{
private A foo;
public X(A concrete)
{
foo = concrete;
}
public FunnyMethod()
{
foo.DoJOB();
}
}
في حين أن إنشاء فئة الحادي عشر تريد تحديد الفئة المستمدة (ب أو ج) يجب استخدامها. فكرت في تمرير مثيل من B أو C باستخدام مُنشئ X.
X kewl = new X(new C());
kewl.FunnyMethod(); //calls C.DoJOB()
kewl = new X(new B());
kewl.FunnyMethod(); // calls B.DoJOB()
أظهر اختباري أن إعلان طريقة مع المعلمة A لا تعمل. هل فاتني شيء؟ كيف يمكنني تنفيذ هذا بشكل صحيح؟
(أ مجردة ، لا يمكن إنشاء مثيل لها)
تعديل:آسف ، لقد نسيت sth.
الفئة A هي المفرد التجريدي العام:
abstract public class A<T> where T : A<T>
{
....
}
public sealed class B : A<B>
{
.....
}
public sealed class C : A<C>
{
.....
}
انظر المثال:http://www.c-sharpcorner.com/uploadfile/snorrebaard/genericsingleton1172008110419am/genericsingleton.aspx
تحت خط الرأس "الحل مع المفرد العام كطبقة مجردة"
المحلول
لتعديلك:
void Main()
{
var kewl = new X<C>(new C());
kewl.FunnyMethod(); //calls C.DoJOB()
var kewl2 = new X<B>(new B());
kewl2.FunnyMethod(); // calls B.DoJOB()
}
public class X <T> where T : A<T>
{
private A<T> foo;
public X(A<T> concrete)
{
foo = concrete;
}
public void FunnyMethod()
{
foo.DoJOB();
}
}
public abstract class A<T> where T : A<T>
{
public abstract void DoJOB();
}
public class B : A<B>
{
public override void DoJOB()
{
Console.WriteLine("B");
}
}
public class C : A<C>
{
public override void DoJOB()
{
Console.WriteLine("C");
}
}
نصائح أخرى
يجب أن تكون قد ارتكبت خطأ في الاختبار ، يعمل الرمز بشكل جيد:
void Main()
{
X kewl = new X(new C());
kewl.FunnyMethod(); //calls C.DoJOB()
kewl = new X(new B());
kewl.FunnyMethod(); // calls B.DoJOB()
}
public class X
{
private A foo;
public X(A concrete)
{
foo = concrete;
}
public void FunnyMethod()
{
foo.DoJOB();
}
}
public abstract class A
{
public abstract void DoJOB();
}
public class B : A
{
public override void DoJOB()
{
Console.WriteLine("B");
}
}
public class C : A
{
public override void DoJOB()
{
Console.WriteLine("C");
}
}
المخرجات:
ج
ب
يعمل لدي. أحصل على المتوقع
I did something interesting!
So Did I!
عندما أقوم بتشغيله.
الصق هذا في الاستوديو البصري الخاص بك ودخنه
using System;
namespace TestDrive
{
class Program
{
static void Main( string[] args )
{
ServiceConsumer x = new ServiceConsumer( new ConcreteService2() ) ;
x.FunnyMethod() ;
return ;
}
}
abstract class AbstractService
{
public abstract void DoSomethingInteresting() ;
}
class ConcreteService1 : AbstractService
{
public override void DoSomethingInteresting()
{
Console.WriteLine("I did something interesting!");
return ;
}
}
class ConcreteService2 : ConcreteService1
{
public override void DoSomethingInteresting()
{
base.DoSomethingInteresting() ;
Console.WriteLine("So Did I!");
return ;
}
}
class ConcreteService : AbstractService
{
public override void DoSomethingInteresting()
{
Console.WriteLine("Not It's my turn to do something interesting!") ;
return ;
}
}
class ServiceConsumer
{
private AbstractService Service ;
public ServiceConsumer( AbstractService serviceInstance )
{
this.Service = serviceInstance ;
return ;
}
public void FunnyMethod()
{
Service.DoSomethingInteresting() ;
return ;
}
}
}
هتافات!
لست متأكدًا من أنني أفهم السؤال ، إليك تنفيذي وهو يعمل:
مساحة الاسم csharpconsole {
public abstract class A {
public abstract void Test();
}
public class B : A {
public override void Test() {
System.Console.WriteLine("B:Test called!");
}
}
public class C : A {
public override void Test() {
System.Console.WriteLine("C:Test called!");
}
}
class Program {
private A _concrete;
public Program(A concrete) {
_concrete = concrete;
}
public void DoTest() {
_concrete.Test();
}
static void Main(string[] args) {
Program pb = new Program(new B());
pb.DoTest();
Program pc = new Program(new C());
pc.DoTest();
}
}
}