【发布时间】:2016-01-21 12:12:51
【问题描述】:
我提到我与 DTO 的合作不多。我在 DataTransfereObjects 上玩弄多态主义。我想不出一个好的解决方案,所以我制作了这个代码示例来掌握多态与 DataTransfereObjects 和不同的逻辑实现,使用多态、泛型、接口、抽象等。
请检查代码。提示我有什么不好,可以做得更好或更容易。检查accessmodifier,还要检查SOLID(认为我没有正确理解它)。最后好像太复杂了,这样解决是不是很常见?
实际上,我尝试调用一些(反)序列化程序逻辑,它使用 baseDto 来获取派生的 dto,而不会丢失它们的特定信息。该代码应该是解决此类问题的干净抽象沙箱。
void Main()
{
var twoIngrDto = new TwoIngredientsDto();
var threeIngrDto = new ThreeIngredientsDto();
var twoIngrMulAnswerChecker = new TwoIngredientsMultiplicationAnswerChecker();
var threeIngrAddAnswerChecker = new ThreeIngredientsAdditionAnswerChecker();
twoIngrMulAnswerChecker.IsTheAnswerCheckImplementationTheAnswer(twoIngrDto); //TRUE .Dump();
threeIngrAddAnswerChecker.IsTheAnswerCheckImplementationTheAnswer(threeIngrDto); //TRUE .Dump();
twoIngrMulAnswerChecker.IsTheAnswerCheckImplementationTheAnswer(threeIngrDto); //FALSE .Dump();
IAnswerCheck answerchecker = new IngredientsAnswerChecker();
answerchecker.CheckAnswer(twoIngrMulAnswerChecker, twoIngrDto); //TRUE .Dump();
answerchecker.CheckAnswer(threeIngrAddAnswerChecker, threeIngrDto); //TRUE .Dump();
/// QUESTION: How can I use the answerchecker 'twoIngrMulAnswerChecker' with the derived DTO 'threeIngrDto'
/// It failes with following error:
/// The type 'UserQuery.TwoIngredientsMultiplicationAnswerChecker' cannot be used as
/// type parameter 'T' in the generic type or method 'UserQuery.IngredientsAnswerChecker.CheckAnswer<T,DTO>(T, DTO)'.
/// There is no implicit reference conversion from 'UserQuery.TwoIngredientsMultiplicationAnswerChecker'
/// to 'UserQuery.TheAnswerChecker<UserQuery.ThreeIngredientsDto>'.
//answerchecker.CheckAnswer(twoIngrMulAnswerChecker, threeIngrDto).Dump();
answerchecker.CheckAnswer(twoIngrMulAnswerChecker, (TwoIngredientsDto)threeIngrDto).Dump(); // is casting the solution?
}
interface IAnswerCheck
{
bool CheckAnswer<T, DTO>(T answerCkecker, DTO ingredientsDto)
where T : TheAnswerChecker<DTO>
where DTO : IngredientDto;
}
public abstract class TheAnswerChecker<T> where T : IngredientDto
{
internal abstract int TheAnswerCheckImplementation(T answerIngredietsDto);
private int TheAnswer {get { return 42;} }
public bool IsTheAnswerCheckImplementationTheAnswer(T answerIngredietsDto)
{
return TheAnswer == TheAnswerCheckImplementation(answerIngredietsDto);
}
}
//generate a base class
public class IngredientsAnswerChecker : IAnswerCheck //: TheAnswerChecker<IngredientDto>
{
public bool CheckAnswer<T, DTO>(T answerCkecker, DTO ingredientsDto)
where T : TheAnswerChecker<DTO>
where DTO : IngredientDto
{
return answerCkecker.IsTheAnswerCheckImplementationTheAnswer(ingredientsDto);
}
}
public class TwoIngredientsMultiplicationAnswerChecker : TheAnswerChecker<TwoIngredientsDto>
{
internal override int TheAnswerCheckImplementation(TwoIngredientsDto answerIngredietsDto) //where T : TwoIngredientsDto
{
return answerIngredietsDto.A * answerIngredietsDto.B;
}
}
public class ThreeIngredientsAdditionAnswerChecker : TheAnswerChecker<ThreeIngredientsDto>
{
internal override int TheAnswerCheckImplementation(ThreeIngredientsDto answerIngredietsDto)
{
return answerIngredietsDto.A + answerIngredietsDto.B + answerIngredietsDto.C;
}
}
public class IngredientDto
{
public IngredientDto()
{
Id = Guid.NewGuid();
}
public Guid Id { get; private set; }
}
public class TwoIngredientsDto : IngredientDto
{
public virtual int A {get {return 6;}}
public virtual int B {get {return 7;}}
}
public class ThreeIngredientsDto : TwoIngredientsDto
{
public override int B {get {return 24;}}
public int C {get {return 12;}}
}
【问题讨论】:
标签: c# generics polymorphism dto solid-principles