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();
}