C#一个列表中的不同类对象

C#一个列表中的不同类对象,c#,list,generics,interface,polymorphism,C#,List,Generics,Interface,Polymorphism,我现在环顾了一些地区,想找到解决这个问题的办法。我找到了几种解决方法,但说实话,我没有意识到哪种方法被认为是“正确的”C#或OOP解决方法。我的目标不仅是解决这些问题,而且还要开发一套好的代码标准,我确信有一种标准的方法来处理这个问题 假设我有两种类型的打印机硬件及其各自的类和通信方式:PrinterType1和PrinterType2 我也希望能够在以后添加另一种类型,如果必要的话。抽象的一步是,它们有很多共同点。作为示例,应该可以向它们中的每一个发送一个字符串。它们都有共同的变量,每个类都有

我现在环顾了一些地区,想找到解决这个问题的办法。我找到了几种解决方法,但说实话,我没有意识到哪种方法被认为是“正确的”C#或OOP解决方法。我的目标不仅是解决这些问题,而且还要开发一套好的代码标准,我确信有一种标准的方法来处理这个问题

假设我有两种类型的打印机硬件及其各自的类和通信方式:PrinterType1和PrinterType2

我也希望能够在以后添加另一种类型,如果必要的话。抽象的一步是,它们有很多共同点。作为示例,应该可以向它们中的每一个发送一个字符串。它们都有共同的变量,每个类都有唯一的变量。(例如,一个通过COM端口通信并具有这样的对象,而另一个通过TCP通信并具有这样的对象)

然而,我只想实现一个所有这些打印机的列表,并且能够遍历该列表并在所有打印机上执行“发送(字符串消息)”之类的操作,而不管类型如何。我还希望访问两个对象相同的变量,如“PrinterList[0].Name”,但在某些位置,我还希望访问特定于对象本身的数据(例如,在应用程序的“设置”窗口中,其中一个对象设置了COM端口名,另一个对象设置了IP/端口号)

因此,简言之:

共同点:

  • 名字
  • 发送()
特定于PrinterType1:

  • 港口
特定于PrinterType2:

  • 知识产权
例如,我希望对所有对象执行Send(),而不考虑对象的类型和数量

我读过多态性、泛型、接口等等,但我想知道,在我看来,这个基本问题通常是如何在C#(和/或OOP)中处理的

实际上,我确实尝试创建一个基类,但对我来说似乎不太合适。例如,我在基类本身中没有使用“stringsend(stringmessage)”函数。那么,为什么我要在派生类中定义一个需要重写的函数,而我从来不会在基类中使用这个函数呢

我真的很感谢你的回答。这里的人似乎很有知识,这个地方早些时候为我提供了很多解决方案。现在我终于有了一个帐户来回答和投票了

编辑:

为了进一步解释,我还希望能够访问实际printertype的对象。例如,PrinterType1中的端口变量是SerialPort对象。我想通过以下方式访问它:
PrinterList[0]。Port.Open()

并可访问参考底图端口的全部功能。同时,我想调用通用函数,这些函数对不同的对象以相同的方式工作(但使用不同的实现):


创建一个包含“常用”方法的接口(比如说
IPrinterType
),并改用此接口。

一个使用接口的伪示例

public interface IPrinter
{
   void Send();
   string Name { get; }
}

public class PrinterType1 : IPrinter
{
  public void Send() { /* send logic here */ }
  public string Name { get { return "PrinterType1"; } }
}

public class PrinterType2 : IPrinter
{
  public void Send() { /* send logic here */ }
  public string Name { get { return "Printertype2"; } }

  public string IP { get { return "10.1.1.1"; } }
}


// ...
// then to use it
var printers = new List<IPrinter>();

printers.Add(new PrinterType1());
printers.Add(new PrinterType2());

foreach(var p in printers)
{
  p.Send();

  var p2 = p as PrinterType2;

  if(p2 != null) // it's a PrinterType2... cast succeeded
    Console.WriteLine(p2.IP);
}
公共接口IPrinter
{
无效发送();
字符串名称{get;}
}
公共类PrinterType1:IPrinter
{
public void Send(){/*此处发送逻辑*/}
公共字符串名称{get{return“PrinterType1”;}
}
公共类PrinterType2:IPrinter
{
public void Send(){/*此处发送逻辑*/}
公共字符串名称{get{return“Printertype2”;}
公共字符串IP{get{返回“10.1.1.1”;}
}
// ...
//然后使用它
var printers=新列表();
Add(新的PrinterType1());
添加(新的PrinterType2());
foreach(打印机中的var p)
{
p、 Send();
变量p2=p作为PrinterType2;
if(p2!=null)//这是一个PrinterType2…转换成功
控制台写入线(p2.IP);
}

您描述的内容与设计接口的目的基本相同。将所有通用属性/方法放入其中,并隐藏具体的实现。我仍然建议使用一个基本的
打印机
类,因为很明显会有类似的代码可以共享


当涉及到您提到的更明确的属性时,例如端口/IP,您必须知道您要处理的是什么类型。此时,您可以将其转换为正确的类型。

您要查找的是一个抽象基类,如下所示:

abstract class Printer
{
    public string Name { get; set; }
    public abstract string Send(string Message);
}
然后从该类继承并根据需要实现Send()函数


您也可以在这里使用接口。区别在于接口只能指定继承者必须实现的属性、方法和事件——它本身不实现任何代码。您使用哪一种取决于什么最适合您的应用程序。您可能会同时完成这两项工作(创建一个实现接口的抽象类)。

对于“例如,我没有使用”字符串发送(字符串消息)的特定问题“函数在基类本身中。那么,为什么我要在派生类中定义一个需要重写的函数,而我从来没有在基类中使用过这个函数?”

实际上没有必要在基类中实现它

如果您的基类是一个抽象类,那么您可以简单地声明它,然后让具体的类来实现它


如果您不想提供任何具体的实现,那么最好使用一个接口,而不是一个抽象类,该接口要求所有具体类都要实现。

我建议,无论您在这种特定情况下使用哪种解决方案,您都可以选择一本关于OOP基础知识的好书。一本好书也会提供示例d我相信你会看到何时以及如何使用你将选择的语言的每一项功能。+1.感谢你想要开发一套好的代码标准。谢谢你的回答。我已经调查了一些接口,但是从我的
abstract class Printer
{
    public string Name { get; set; }
    public abstract string Send(string Message);
}