Domanda

Ho una classe astratta A, dove ho derivato la classe B e C. Una classe fornisce un metodo DoJOB abstract (), che viene realizzato tramite due classi derivate.

C'è una classe X, che ha metodi all'interno, che hanno bisogno di chiamare DoJOB (). La classe X non può contenere alcun codice come B.DoJOB () o C.DoJOB ().

Esempio:

public class X
{
private A foo;

public X(A concrete)
{
foo = concrete;
}

public FunnyMethod()
{
foo.DoJOB();
}

}

Mentre istanziare la classe X voglio decidere quale classe derivata (B o C) deve essere utilizzato. Ho pensato di passare un'istanza di B o C utilizzando il costruttore di X.

X kewl = new X(new C());
kewl.FunnyMethod(); //calls C.DoJOB()

kewl = new X(new B());
kewl.FunnyMethod(); // calls B.DoJOB()

Il mio test ha dimostrato che dichiara un metodo con un parametro A non funziona. Mi sto perdendo qualcosa? Come posso implementare correttamente questo?

(A è astratta, non può essere istanziato)

Modifica Scusa, ho dimenticato qc.

classe A è un generico Singleton astratto:

abstract public class A<T> where T : A<T>
{
    ....
}

public sealed class B : A<B>
{
    .....
}

public sealed class C : A<C>
{
    .....
}

Si veda l'esempio: http://www.c-sharpcorner.com/UploadFile/snorrebaard/GenericSingleton11172008110419AM /GenericSingleton.aspx

Sotto la linea di testa "La soluzione con il Singleton generico come una classe astratta"

È stato utile?

Soluzione

Per la tua modifica:

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");
    }
}

Altri suggerimenti

Si deve aver fatto un errore nel test, il codice funziona bene:

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");
    }
}

Uscite:
C
B

funziona per me. Ho l'aspettavo

I did something interesting!
So Did I!

quando l'eseguo.

Incolla questo nella vostra Visual Studio e il fumo è

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 ;
        }
    }
}

Cheers!

Non sono sicuro di aver capito la domanda, ecco la mia implementazione e funziona:

namespace 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();
    }
}

}

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top