例如,我有两个班级
public class A
{
public Guid Id { get; set;}
public string Type { get; set; }
public string State { get; set; }
public string SomeProperty { get; set; }
}
public class B
{
public Guid Id { get; set; }
public string Type { get; set; }
public string State { get; set; }
public string AnotherProperty { get; set; }
}
每个类都有自己的存储库
public class RepA
{
public void Add(A entity)
{
// some specific logic here
}
public void Delete(A entity)
{
// some specific logic here
}
}
public class RepB
{
public void Add(B entity)
{
// some specific logic here
}
public void Delete(B entity)
{
// some specific logic here
}
}
我需要实现一种方法来保存具有动态类型的实体列表。我想避免使用嵌套的“switch”结构(如下所列),因为我有2种以上的类型和2种以上的状态,代码看起来很乱。
private readonly RepA _repA = new RepA();
private readonly RepB _repB = new RepB();
public void SaveChanges(List<dynamic> entities)
{
foreach (var entity in entities)
{
switch (entity.Type)
{
case "A":
var a = entity as A;
switch (entity.State)
{
case "Added":
_repA.Add(a);
break;
case "Deleted":
_repA.Delete(a);
break;
}
break;
case "B":
var b = entity as B;
switch (entity.State)
{
case "Added":
_repB.Add(b);
break;
case "Deleted":
_repB.Delete(b);
break;
}
break;
}
}
}
您能否提出其他解决方案? 我想过基类和基础库的接口。但在这种情况下,何时以及如何初始化_repo,这取决于实体类型?
private IBaseRep _repo;
public void SaveChanges(List<dynamic> entities)
{
foreach (var entity in entities)
{
switch (entity.State)
{
case "Added":
_repo.Add(entity)
break;
case "Deleted":
_repo.Delete(entity)
break;
}
}
}
答案 0 :(得分:1)
visitor pattern专门用于处理同类列表。
答案 1 :(得分:0)
您的实体类A
和B
正在违反DRY原则。下面怎么样?我能想到的一个问题是实体集合的多个枚举,但我不确定你的集合有多大,以确定这是否真的是一个问题。
public abstract class Entity
{
public Guid Id { get; set; }
public string Type { get; set; }
public string State { get; set; }
}
public class A : Entity
{
public string SomeProperty { get; set; }
}
public class B : Entity
{
public string AnotherProperty { get; set; }
}
public abstract class Rep<T> where T : Entity
{
public abstract void Add(T entity);
public abstract void Delete(T entity);
public virtual void SaveChanges(IEnumerable<T> entities)
{
foreach (var entity in entities)
{
switch (entity.State)
{
case "Added":
Add(entity);
break;
case "Deleted":
Delete(entity);
break;
default:
throw new InvalidOperationException($"Invalid entity state {entity.State}");
}
}
}
}
public class RepA : Rep<A>
{
public override void Add(A entity)
{
// some specific logic here
}
public override void Delete(A entity)
{
// some specific logic here
}
}
public class RepB : Rep<B>
{
public override void Add(B entity)
{
// some specific logic here
}
public override void Delete(B entity)
{
// some specific logic here
}
}
public class Program
{
private static readonly RepA _repA = new RepA();
private static readonly RepB _repB = new RepB();
public static void Main()
{
var entities = new List<Entity>();
// fill the list here
_repA.SaveChanges(entities.OfType<A>());
_repB.SaveChanges(entities.OfType<B>());
}
}