Вся идея, связанная с генериками, состоит в том, чтобы иметь общий код, поэтому тип этого класса можно рассматривать одинаково. Из того, что вы опубликовали, не легко увидеть, какой у вас общий код.
Ниже у меня есть класс, который имеет некоторый общий код:
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;
}
}
Вы можете увидеть в приведенном выше классе, когда он разбирает строку в Guid
от this.Input.Something
, а затем он выполняет ==
на него this.Ouput.SomeGuid
, компилятор счастлив, потому что мы сделали ограничение, что TInput
должен реализовать интерфейс ITInput
так что компилятор знает, эта линия будет работать и Input
будет Something
как string
собственности:
Guid.Parse(this.Input.SomeThing)
Компилятору все равно, какой тип бетона до тех пор, пока Something
не доступен. Это та же идея для TOuput
, но компилятор ожидает, что он реализует ITOutput
, поэтому он ожидает Guid
в SomeGuid
. Вот почему компилятор с удовольствием разбирает строку в руководстве, а затем выполняет оператор ==
на ней с другой вещью, которая также является 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();
}
Вы можете увидеть в foreach
независимо от конкретный тип, мы можем назвать Input
, Output
и IsInputAGuid()
на всех из них.
Итак, в коде найдите, какой код является общим, а затем примените к нему вышеуказанную технику. Вы можете использовать интерфейсы или базовый класс для своих ограничений.
'Mangler' и 'Mangler ' - это совершенно разные типы, поэтому единственным общим списком для их хранения может быть «Список
Проверьте [Ковариация и контравариантность] (https://blogs.msdn.microsoft.com/csharpfaq/2010/02/16/covariance-and-contravariance-faq/). –
@AlexB. Хороший комментарий, хотя 'string' и' int' и 'byte []' и 'Guid' - несколько несвязанные типы. – Codor