以抽象类作为参数的方法

发布于 2024-10-10 17:46:25 字数 1138 浏览 8 评论 0原文

我有一个抽象类 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();
}

}

在实例化类 XI 时,想要决定必须使用哪个派生类(B 或 C)。 我考虑过使用 X 的构造函数传递 B 或 C 的实例。

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

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

我的测试表明,声明带有参数 A 的方法不起作用。我错过了什么吗? 我怎样才能正确实施这个?

(A是抽象的,它不能被实例化)

编辑: 抱歉,我忘记了某件事。

类 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/GenericSingleton11172008110419AM /GenericSingleton.aspx

在标题行“通用单例作为抽象类的解决方案”下

I have an abstract class A, where I have derived the classes B and C.
Class A provides an abstract method DoJOB(), which is implemented by both derived classes.

There is a class X which has methods inside, which need to call DoJOB().
The class X may not contain any code like B.DoJOB() or C.DoJOB().

Example:

public class X
{
private A foo;

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

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

}

While instantiating class X I want to decide which derived class (B or C) must be used.
I thought about passing an instance of B or C using the constructor of X.

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

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

My test showed that declaring a method with a parameter A is not working. Am I missing something?
How can I implement this correctly?

(A is abstract, it cannot be instantiated)

EDIT:
Sorry, I forgot sth.

class A is a generic abstract singleton:

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

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

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

See the example:
http://www.c-sharpcorner.com/UploadFile/snorrebaard/GenericSingleton11172008110419AM/GenericSingleton.aspx

Under the head line "The solution with the Generic Singleton as an abstract class"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

苏佲洛 2024-10-17 17:46:25

您一定在测试中犯了错误,代码工作正常:

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

输出:

C

You must have made a mistake in the test, the code works fine:

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

Outputs :

C

B

风流物 2024-10-17 17:46:25

对于您的编辑:

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

For your edit:

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");
    }
}
会傲 2024-10-17 17:46:25

对我有用。 我得到了预期的结果

I did something interesting!
So Did I!

当我运行它时,

。将其粘贴到您的 Visual Studio 中并使用它

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

干杯!

Works for me. I get the expected

I did something interesting!
So Did I!

when I run it.

Paste this in your Visual Studio and smoke it

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!

阳光①夏 2024-10-17 17:46:25

我不确定我是否理解这个问题,这是我的实现并且它有效:

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

}

I'm not sure I understand the question, here is my implementation and it works:

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

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文