Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.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#_Oop - Fatal编程技术网

C# 如何实现具有相同方法的多个类来做不同的事情?

C# 如何实现具有相同方法的多个类来做不同的事情?,c#,oop,C#,Oop,我是一名主要从事嵌入式设备(用C和汇编编程)的开发人员。我的C#和OOP知识非常有限(尽管我可以在必要时假装通过它)。我有五台设备通过USB与PC接口。电脑进行一些计算并将结果发送到设备。对每个设备执行相同的计算,但计算方式不同。对于每台设备,我都有一个C#Windows窗体应用程序,它可以执行一些工作并将数据来回发送到设备。目前,我正在尝试将五个不同的应用程序合并为一个,这样我们就可以轻松地进行更改,轻松地添加新设备,并拥有一个标准的用户界面。我的问题是,我不知道最好的方法是什么,因为在运行时

我是一名主要从事嵌入式设备(用C和汇编编程)的开发人员。我的C#和OOP知识非常有限(尽管我可以在必要时假装通过它)。我有五台设备通过USB与PC接口。电脑进行一些计算并将结果发送到设备。对每个设备执行相同的计算,但计算方式不同。对于每台设备,我都有一个C#Windows窗体应用程序,它可以执行一些工作并将数据来回发送到设备。目前,我正在尝试将五个不同的应用程序合并为一个,这样我们就可以轻松地进行更改,轻松地添加新设备,并拥有一个标准的用户界面。我的问题是,我不知道最好的方法是什么,因为在运行时之前我不知道将使用哪个设备。我试图避免一堆if语句,我希望能够将每个设备放在一个单独的文件中。这是我所说的一些psudo代码

class Device //This is what EVERY device can do
{
...
DoWork1();
DoWork2();
DoWork3();
...
}

class Device1
{
...
DoWork1(); //This is how the work is done for this device
DoWork2();
DoWork3();
...
}

class Device2
{
...
DoWork1();  //This is how the work is done for this device (not the same way as   Device1)
DoWork2();
DoWork3();
}


public partial class frmMain : Form
{
private (some kind of object or something) CurrentDevice;
public frmMain()
{
...
//Determine what device (could be one of five) is currently being used
CurrentDevice = (which device is currently being used)
//Could be CurrentDevice = new Device1();
}
}

private void Button1_Click()
{
CurrentDevice.DoWork1(); //But this could be Device1.DoWork1() or Device2.DoWork1(), depending on what device is currently being used (which was determined in the frmMain constructor)
}
我不是很确定,但我想我可以使用一个接口,或者可以为设备类继承Device1类并重写这些方法……但我不知道如何用一种通用的方式来表示CurrentDevice.DoWork1(),因为CurrentDevice可以是Device1或Device2

任何想法都将不胜感激。我在WindowsXPSP3和Windows7上使用带.NET3.5的VisualStudio2008

我希望我对这个问题描述得足够好。如果没有,或者我没有提到我应该提到的事情,请告诉我。我是stackoverflow和C#的新手

谢谢,


Michael

您可能会有兴趣了解这方面的一些设计模式。

具体的抽象工厂和模板方法。我想其中一个可能就是你要找的。


据我所知,您希望能够拥有一个基类,然后继承基类函数并在子类中定义它们。其中一种模式可能适用于您的场景。

在您的案例中,您基本上定义了一个继承层次结构,它可以由一个抽象基类和两个派生类型组成,也可以由一个具有两个实现者的接口组成。比如说

public abstract class BaseDevice
{
    public abstract void DoWork1();
}

public class Device1 : BaseDevice
{
    public override void DoWork1()
    {
        // provide implementation here
    }
}

// also create Device2 : BaseDevice and implement 
或者可以利用接口定义

public interface IDevice
{
    void DoWork1();
}

public class Device1 : IDevice
{
    public void DoWork1() 
    {
        // provide implementation 
    }
}
你选择哪种方法取决于你自己。例如,如果您希望使用整个层次结构中常见的实现来定义某些行为或属性,那么您可能会倾向于使用抽象基类。通过抽象类,您可以提供实现。接口是一个空契约,您不能提供任何常见行为,只能定义可能存在的行为或属性

无论采用哪种方式,都会通过抽象或接口基引用派生类型更多的实例。通过这种方式,您不关心实现类型是什么,只关心它能做什么(它的方法或属性)

例如:

 BaseDevice device1 = new Device1(); 
 BaseDevice device2 = new Device2();
 // maybe you have a list?
 List<BaseDevice> devices = new List<BaseDevice> { device1, device2 };

 foreach (BaseDevice device in devices)
 {
      device.DoWork1(); // notice you don't care about the actual type, just the behavior
 }
baseDevice1=新设备1();
BaseDevice2=新设备2();
//也许你有清单?
列表设备=新列表{device1,device2};
foreach(设备中的基本设备)
{
device.DoWork1();//注意,您不关心实际的类型,只关心行为
}

一开始我有点困惑,因为在这种情况下,pc进行计算,而设备只接收结果。所以据我所知,你需要在PC上实现不同的东西,而不是设备本身

这里真正的诀窍不是使用接口或继承-您已经明白了这一点。诀窍在于获得正确的实现类型,并使用工厂来完成该部分。

但您也必须决定继承还是接口

只有当“某物”确实是一个普通但又有意义的家族的一部分时,才使用继承。继承应该有一个非常强的“is a”元素

可能存在许多可以进行计算但不希望创建族的对象。这就是组合有用的地方。要通过继承实现这一点,您需要让它们共享一个公共基类。在这里,您可以使用合成来允许每个对象使用公共接口来允许pc执行计算

我建议采用这种方法

您应该有一个对通用接口、IDoCalculation或类似接口的引用,该接口定义了一个方法签名,该签名将以相同的方式为任何设备调用

接下来,您必须获得该接口的特定于设备的实现,这是每个设备可以具有不同实现的地方。为每个设备类型/实现创建一个类

现在的诀窍是在不知道所需内容的情况下获得所需的类。要再次隐藏细节并使方法调用通用,可以创建一个参数化工厂。此工厂接受一个参数,该参数描述pc需要计算的设备。然后,它解释该参数,并基于该参数创建一个实现IDoCalculation的特定类。这是返回的,您就完成了

我留给你们去弄清楚这些对象需要如何组织成不同的集合

//Common interface
public interface IDoCalculation
{
    //Use whatever method signatures you need
    int DoCalculation();
}

public class DeviceImplementation1 : IDoCalculation
{


    #region IDoCalculation Members

    public int DoCalculation()
    {
        //Device 1 Specific code goes here
    }

    #endregion
}

public class DeviceImplementation2 : IDoCalculation
{


    #region IDoCalculation Members

    public int DoCalculation()
    {
        //Device 2 Specific code goes here
    }

    #endregion
}

// A simple factory that does not require a lot of OOP understanding.
public class DeviceCalculationFactory
{
    //Return a correct implementor based on the device type passed in
    public IDoCalculation GetCalculationImplementationInstance(string devicetype)
    {
        switch (devicetype)
        {
            case "Device1":
                return new DeviceImplementation1();

            case "Device2":
                return new DeviceImplementation2();
            default:
                //TODO ???
                return null;

        }

    }

}

// A simple client that calls the methods and then send the results
public class DeviceManager
{
    //To do the calculation, get an implementor for the correct device type from the factory - Presumably the PC knows the device of interest, example "Device1"
    public void DoTheCalculationThing(string deviceType)
    {


        DeviceCalculationFactory factory = new DeviceCalculationFactory();
        IDoCalculation calculation = factory.GetCalculationImplementationInstance(deviceType);
        int result = calculation.DoCalculation();
        // now send the result to the device

    }

}

Anthony Pegram的回答很好,但你可能想更进一步。可以想象的是,尽管看起来您的所有设备都在执行相同的任务,但您可能会发现有些设备实际上并没有执行所有的任务,而有些设备执行的任务甚至更多

在这种情况下,您可能会试图更改接口以添加另一个
DoWork5
DoWork6
方法,并对不具有特定行为的类型简单地引发
NotImplemented
异常

这很麻烦,原因很多。我建议(如果你发现自己处在这个职位上的话)看看如何明确你的角色。你这样做