C# 构造函数中的抽象类型而不是具体类型

C# 构造函数中的抽象类型而不是具体类型,c#,.net,polymorphism,abstract-class,C#,.net,Polymorphism,Abstract Class,我有一个对象,假设它是数据,在 他们称之为web方法 // NewData1.cs public NewData1(Concrete1 con) { ID = con.ID; var results= con.listOfResults(); var something= con.GetSomething(); Something =

我有一个对象,假设它是数据,在 他们称之为web方法

        // NewData1.cs
        public NewData1(Concrete1 con)
        {
            ID = con.ID;
            var results= con.listOfResults();

                var something= con.GetSomething();
                Something = new List<Somethings>();

                con.DoSomething();
            }

            // NewData2.cs
            public NewData2(Concrete2 con)
            {
                ID = con.ID;
                var results= con.listOfResults();

                var something= con.GetSomething();
                Something = new List<Somethings>();

                con.DoSomething();
            }

            // NewData3.cs
            public NewData3(Concrete3 con)
            {
                ID = con.ID;
                var results= con.listOfResults();

                var something= con.GetSomething();
                Something = new List<Somethings>();

                con.DoSomething();
            }
//NewData1.cs
公共新数据1(混凝土1 con)
{
ID=con.ID;
var results=con.listOfResults();
var something=con.GetSomething();
Something=新列表();
con.DoSomething();
}
//NewData2.cs
公共新数据2(混凝土2 con)
{
ID=con.ID;
var results=con.listOfResults();
var something=con.GetSomething();
Something=新列表();
con.DoSomething();
}
//NewData3.cs
公共新数据3(混凝土3 con)
{
ID=con.ID;
var results=con.listOfResults();
var something=con.GetSomething();
Something=新列表();
con.DoSomething();
}
正如您所看到的,这些类做同样的事情(它不是我的代码..我想更改它)。 唯一不同的是具体类型(1,2,3),它们在调用方法时执行不同的逻辑


您知道如何将这些类简化为一个类,但仍然使它们各自具有其特殊的逻辑而不相同吗?

您想要一个抽象基类:

public abstract class BaseClass
{
    // Use protected fields to store data that only this class and derived
    // classes can access.
    protected List<Something> storedSomethings;

    //Define an abstract method signature for methods that the concrete classes
    // have very different implementations for:
    public abstract List<Something>GetSomethings();

    //Use a virtual method for methods that are identical or similar on 
    //the concrete classes:
    public virtual void AddSomethings(List<Something> addList)
    {
        storedSomethings.Add(addList);
    }
}

创建以下基类

public class Concrete
{
    public int ID { get; set; }

    public virtual something GetSomething()
    {

    }

    public virtual void DoSomething()
    {

    }
}
让你的concrete1、concrete2等课程扩展到Concrete。如果需要,这些类将能够重写GetSomething方法。 那你只需要一个

public NewData2(Concrete con)
{
    ID = con.ID;
    var results= con.listOfResults();

    var something= con.GetSomething();
    Something = new List<Somethings>();

    con.DoSomething();
}
public NewData2(混凝土施工)
{
ID=con.ID;
var results=con.listOfResults();
var something=con.GetSomething();
Something=新列表();
con.DoSomething();
}

如果您的
Concrete1
Concrete2
Concrete3
类共享相同的方法,您可以将其提取到接口中,并使其实现:

// an interface is simply a contract
interface ICanGetSomething
{
    int ID { get; }
    List<Result> ListOfResults();
    Something GetSomething();
}

// your concrete classes should all implement the same interface
class Concrete1 : ICanGetSomething { ... }
class Concrete2 : ICanGetSomething { ... }
class Concrete3 : ICanGetSomething { ... }
如果它们也共享相同的功能,则还可以使用公共抽象类重用所有公共代码:

abstract class Base : ICanGetSomething { ... }

// your concrete classes should all inherit from the same base class
class Concrete1 : Base { ... }
class Concrete2 : Base { ... }
class Concrete3 : Base { ... }

无论哪种方式,我都建议使用接口来定义合同。由于C#不支持多重继承,因此您不希望强制所有具体实现都从单个基类派生(除非有必要)。这仍然意味着您将在有共享功能的地方使用继承,但是您的
NewData
方法应该接受参数的接口,而不是基类。

如果所有3个派生类都具有完全相同的签名,您可以从具体类创建一个抽象基类

public class Concrete
{
    public int ID { get; set; }

    public virtual something GetSomething()
    {

    }

    public virtual void DoSomething()
    {

    }
}
基类:

public abstract class AbstractBaseClass
{
    public long ID { get; set; }
    public abstract List<string> ListOfResults();
    public abstract string GetSomething();
    public abstract void DoSomething();
}
public void NewData(AbstractBaseClass abs)
{
    ID = abs.ID;

    var results= abs.listOfResults();
    var something= abs.GetSomething();
    abs.DoSomething();
}
您现在可以执行以下操作,例如:

NewData data = new NewData(new Concrete1());
NewData构造函数中的所有调用都将定向到Concrete1子类


如果您只能有一个NewData实例,则可以在需要时使用来更改具体类。

不能使用不同类型的参数,除非它们也继承了一个公共基类,或者您可以通过某种方式使其与泛型方法(通常还需要一个公共基类或委托进行转换)一起使用。Peter,如果调用baseClass.GetSomthing,它如何知道要调用什么GetSomthing?Concrete1?Concrete2?Conret3?它将调用您拥有的对象上的方法。因此,如果您将Concrete2传递给newdata,它将对传入的Concrete2实例执行所有操作。这意味着类的静态方法。也许您应该更改您的示例,以反映您的意思是对class@Kazuo:是的,修复最后一个代码段以使其真正编译将是一个好主意。@DevTraveler:Google表示“vtable”或“dynamic dispatch”。对虚拟方法(通常)是如何在引擎盖下工作的有一个很好的解释。注意:首先,基类通常被命名为
base
或其他什么<代码>具体意味着它是抽象的“有用”实现。如果基类不包含抽象方法,则它不必是
抽象的。Tbh我更喜欢你的答案是使用我在给出答案后想到的界面。但是现在已经完成了,没有必要改变它来匹配已经存在的答案。我会编辑我的,并把它留在这里,以防有人能从中得到任何用处。
public abstract class AbstractBaseClass
{
    public long ID { get; set; }
    public abstract List<string> ListOfResults();
    public abstract string GetSomething();
    public abstract void DoSomething();
}
public class Concrete1 : AbstractBaseClass
{
    public override List<string> ListOfResults()
    {
        // Logic
    }

    public override string GetSomething()
    {
        // Logic
    }

    public override void DoSomething()
    {
        // Logic
    }
}
public void NewData(AbstractBaseClass abs)
{
    ID = abs.ID;

    var results= abs.listOfResults();
    var something= abs.GetSomething();
    abs.DoSomething();
}
NewData data = new NewData(new Concrete1());