Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何引用抽象类_C#_Abstract Class - Fatal编程技术网

C# 如何引用抽象类

C# 如何引用抽象类,c#,abstract-class,C#,Abstract Class,在发布这个问题时,我希望找到一种方法来引用/指向 工人/持有者可以使用的抽象类 正如@progman和@laryx decaloa的评论所建议的那样,没有办法保存对抽象类的引用,但只能保存对实例化对象的引用 下面你可以找到我认为是他们提出的解决方案。对我来说,这是一个丑陋的解决方案,我希望有一个从抽象基类派生多个静态类的解决方案,并且持有者获得对这些静态类的引用来完成它的工作。从抽象类派生静态类似乎是设计所禁止的,表明体系结构不好;虽然我不明白为什么上面的解决方案更好 建议的解决方案 using

在发布这个问题时,我希望找到一种方法来引用/指向 工人/持有者可以使用的抽象类

正如@progman和@laryx decaloa的评论所建议的那样,没有办法保存对抽象类的引用,但只能保存对实例化对象的引用

下面你可以找到我认为是他们提出的解决方案。对我来说,这是一个丑陋的解决方案,我希望有一个从抽象基类派生多个静态类的解决方案,并且持有者获得对这些静态类的引用来完成它的工作。从抽象类派生静态类似乎是设计所禁止的,表明体系结构不好;虽然我不明白为什么上面的解决方案更好

建议的解决方案

using System;
using System.Collections.Generic;

public abstract class BaseClass
{
    // Some declarative knowledge
    public int value;

    protected BaseClass(int value){
        this.value = value;
    }

    // Some procedural
    public abstract void execute();
}

public class ConcreteClass1 : BaseClass
{
    public ConcreteClass1() : base(42) {}

    public override void execute()
    {
        Console.WriteLine("In Concrete1! Value " + value);
    }
}

public class ConcreteClass2 : BaseClass
{
    public ConcreteClass2() : base(8888) { }

    public override void execute()
    {
        Console.WriteLine("In Concrete2! Value " + value);
    }
}

public class Holder
{
    BaseClass activeClass;
    public void setClass(BaseClass newClass){
        activeClass = newClass;
    }

    public void doWork()
    {
        int x;
        activeClass.execute();
        x = activeClass.value * activeClass.value;
        Console.WriteLine("Holder has done its work: " + x);
    }
}

class MainClass
{
    static void Main(string[] args)
    {
        List<BaseClass> classes = new List<BaseClass>();
        classes.Add(new ConcreteClass1());
        classes.Add(new ConcreteClass2());

        Holder holder = new Holder();

        holder.setClass(classes[0]);
        holder.doWork();

        holder.setClass(classes[1]);
        holder.doWork();

        holder.setClass(classes[0]);
        holder.doWork();
    }
}

免责声明:我不说C,但是我怀疑情况类似于C++。其余的答案是基于我的C++和OOP的一般经验。 如果我理解正确,您希望通过基类引用保存派生类对象,并在这些对象上调用多态(“虚拟”)方法。因为您希望这些派生类是“无状态的”(即没有数据成员),所以您认为可以“摆脱”静态(和/或抽象)类

问题是您需要实例化一些东西放入
Holder
对象中,因为引用(或指针)只能引用(指向)具体对象。因此,您需要实例化将通过
Holder
中的引用引用的对象,正如一些评论者已经指出的那样。这就是为什么抽象类不起作用——它们不能被实例化

如果有一种OOP语言支持对类型的引用,再加上一些机制,可以执行以下操作:“嗯,这里是对(可能是摘要)的引用
AnimalTypeRef
基类类型
Animal
AnimalTypeRef
实际上是指派生类类型
Elephant
。现在,用户希望调用一个不使用任何类状态的虚拟方法
Animal::make_noise()
,所以让我们调用相应的方法
Elephant::make_noise())
重写它并返回:-)。“--那么,您就可以按要求执行了

我怀疑这不是在C++或C语言中实现的,因为它没有太多的用例,实际上,同样的事情可以用引用引用具体对象的一般机制来完成。
只要继续从抽象基类派生具体(非抽象)类,就不用担心它们的无状态性。定义和使用没有数据成员的具体对象是完全可以的。实例化它们,然后使用对(抽象)基类的引用初始化一个
Holder
对象。通过基类引用调用多态性方法将完成其余的工作。

< P>免责声明:我不说C,但是我怀疑情况类似于C++。其余的答案是基于我的C++和OOP的一般经验。 如果我理解正确,您希望通过基类引用保存派生类对象,并在这些对象上调用多态(“虚拟”)方法。因为您希望这些派生类是“无状态的”(即没有数据成员),所以您认为可以“摆脱”静态(和/或抽象)类

问题是您需要实例化一些东西放入
Holder
对象中,因为引用(或指针)只能引用(指向)具体对象。因此,您需要实例化将通过
Holder
中的引用引用的对象,正如一些评论者已经指出的那样。这就是为什么抽象类不起作用——它们不能被实例化

如果有一种OOP语言支持对类型的引用,再加上一些机制,可以执行以下操作:“嗯,这里是对(可能是摘要)的引用
AnimalTypeRef
基类类型
Animal
AnimalTypeRef
实际上是指派生类类型
Elephant
。现在,用户希望调用一个不使用任何类状态的虚拟方法
Animal::make_noise()
,所以让我们调用相应的方法
Elephant::make_noise())
重写它并返回:-)。“--那么,您就可以按要求执行了

我怀疑这不是在C++或C语言中实现的,因为它没有太多的用例,实际上,同样的事情可以用引用引用具体对象的一般机制来完成。
只要继续从抽象基类派生具体(非抽象)类,就不用担心它们的无状态性。定义和使用没有数据成员的具体对象是完全可以的。实例化它们,然后使用对(抽象)基类的引用初始化一个
Holder
对象。通过基类引用的多态方法调用将完成其余操作。

只需在“MAGIC HERE”标记处使用
Action
。在某些时候,您需要一个从
Action
继承的非抽象类,以便能够创建一个实例并将其分配给
current\u Action
。但这与您的“我不想实例化其中任何一个”的陈述相冲突,这使得
Action
类型的任何字段都毫无意义。据我所知,hi@progman Action是一个专门的委托(用于引用函数),但我不想包装或引用一个函数,而是一个类。@ManuelPasieka确实如此。您只需使用抽象基类的类名/类型。不过,也许你应该把它改名为dif
In Concrete1! Value 42
Holder has done its work: 1764
In Concrete2! Value 8888
Holder has done its work: 78996544
In Concrete1! Value 42
Holder has done its work: 1764