C# 如何在C中存储不同泛型事物的列表#

C# 如何在C中存储不同泛型事物的列表#,c#,generics,collections,C#,Generics,Collections,比如说我有这个基类 class Mangler<TInput, TOutput> { } 这可能吗?您需要一个非泛型的Mangler基类 List<Mangler> list = new List<Mangler>(); list.Add(new StringToBytesMangler()); list.Add(new IntToGuidMangler()); List List=新列表(); 添加(新的StringToBytesMangler());

比如说我有这个基类

class Mangler<TInput, TOutput>
{
}

这可能吗?

您需要一个非泛型的
Mangler
基类

List<Mangler> list = new List<Mangler>();

list.Add(new StringToBytesMangler());
list.Add(new IntToGuidMangler());
List List=新列表();
添加(新的StringToBytesMangler());
添加(新的IntToGuidMangler());

当然,这意味着您还需要具有依赖于
TInput
TOutput

的方法的非泛型版本。如果我正确理解了这个问题,您尝试的方式是不可能的。类型
StringToBytesMangler
IntToGuidMangler
不是从同一类型派生的。您可以引入共享基类型,但我建议重新考虑设计-即使它们可以存储在同一个集合中,它们在语法上也没有任何共同之处(至少问题中没有显示出来)。

泛型背后的整个思想是拥有泛型代码,以便该类的类型可以被同等对待。从您发布的内容中,不容易看到您拥有的通用代码

下面我有一个类,它有一些通用代码:

class Mangler<TInput, TOutput> 
   where TInput: ITInput 
   where TOutput: ITOutput {

   public TInput Input { get; set; }
   public TOutput Output { get; set; }
   public bool IsInputAGuid() {
      if (Guid.Parse(this.Input.SomeThing) == this.Output.SomeGuid ) {
         return true;
      }

      return false;
   }
}
编译器不关心具体类型是什么,只要有可用的
Something
。这与
toput
的想法相同,但编译器希望它实现
ITOutput
,因此它希望
SomeGuid
中有
Guid
。这就是为什么编译器乐于将字符串解析为guid,然后用另一个东西对其执行
=
运算符,该东西也是
guid

以下是接口和一些实现它们的类:

internal interface ITInput {
   string SomeThing { get; set; }
}

internal interface ITOutput {
   Guid SomeGuid { get; set; }
}

internal class AnotherInput : ITInput {
   public string SomeThing { get; set; }
}

internal class SomeInput : ITInput {
   public string SomeThing { get; set; }
}

internal class SomeOutput : ITOutput {
   public Guid SomeGuid { get; set; }
}

internal class SomeOtherOutput : ITOutput {
   public Guid SomeGuid { get; set; }
}
最后,这里是我们可以一般处理这些问题的用法:

var manglers = new List<Mangler<ITInput, ITOutput>>();

manglers.Add( new Mangler<ITInput, ITOutput>
{ Input = new SomeInput(), Output = new SomeOutput()  } );

manglers.Add( new Mangler<ITInput, ITOutput>
{ Input = new AnotherInput(), Output = new SomeOutput() } );

foreach( var thisMangler in manglers ) {
   var input = thisMangler.Input;
   var output = thisMangler.Output;
   var success = thisMangler.IsInputAGuid();
}
var manglers=newlist();
马槽。添加(新马槽)
{Input=new SomeInput(),Output=new SomeOutput()});
马槽。添加(新马槽)
{Input=new-AnotherInput(),Output=new-SomeOutput()});
foreach(在马槽中的马槽){
var输入=thisMangler.input;
var输出=thisMangler.output;
var success=thisMangler.isInputGuid();
}
您可以在
foreach
中看到,无论具体类型如何,我们都可以调用
Input
Output
IsInputAGuid()


因此,在您的代码中找到哪些代码是泛型的,然后将上述技术应用于它。您可以为约束使用接口或基类。

Mangler
Mangler
是完全不同的类型,因此保存它们的唯一通用列表可以是
列表。也许您可以从另一个基类或接口派生
Mangler
,并将该类型用于列表。请检查。@AlexB。不错的评论,虽然
string
int
byte[]
Guid
是一些不相关的类型。或者
对象
@Sinatr,是的,但这很难看,而且它不允许您定义公开类功能的方法。所以整个想法是使用接口。我理解正确吗?一个接口或基类,它的代码是通用的,这样你就可以对对象一视同仁,因为它们共享一个通用接口。
Guid.Parse(this.Input.SomeThing)
internal interface ITInput {
   string SomeThing { get; set; }
}

internal interface ITOutput {
   Guid SomeGuid { get; set; }
}

internal class AnotherInput : ITInput {
   public string SomeThing { get; set; }
}

internal class SomeInput : ITInput {
   public string SomeThing { get; set; }
}

internal class SomeOutput : ITOutput {
   public Guid SomeGuid { get; set; }
}

internal class SomeOtherOutput : ITOutput {
   public Guid SomeGuid { get; set; }
}
var manglers = new List<Mangler<ITInput, ITOutput>>();

manglers.Add( new Mangler<ITInput, ITOutput>
{ Input = new SomeInput(), Output = new SomeOutput()  } );

manglers.Add( new Mangler<ITInput, ITOutput>
{ Input = new AnotherInput(), Output = new SomeOutput() } );

foreach( var thisMangler in manglers ) {
   var input = thisMangler.Input;
   var output = thisMangler.Output;
   var success = thisMangler.IsInputAGuid();
}