我有这些结构
class A : IFoo {
Foo(){
//do something
}
IList<B> Bs {get;set;}
IList<C> Cs {get;set;}
}
class B : IFoo {
Foo(){
//do something
}
IList<D> Ds {get;set;}
}
class C : IFoo {
Foo(){
//do something
}
}
class D : IFoo {
Foo(){
//do something
}
}
class Helper{
Bar(A a){
a.Foo();
Bar(a.Bs);
Bar(a.Cs);
}
Bar(IList<B> bs)
{
foreach(var b in bs)
{
Bar(b);
}
}
Bar(B b)
{
b.Foo();
Bar(b.Ds);
}
Bar(IList<C> cs)
{
foreach(var c in cs)
{
Bar(c);
}
}
Bar(C c)
{
c.Foo();
}
Bar(IList<D> ds)
{
foreach(var d in ds)
{
Bar(d);
}
}
Bar(D d)
{
d.Foo();
}
}
interface IFoo {
void Foo();
}
如您所见,Helper
类(即方法Bar
)中针对不同类型的A,B,C,IList<A>,IList<B>,IList<C>
重复了大量代码。此外,当一个新的列表属性被添加到类中时,我需要返回并更改Helper类,它与Open / Close主体相矛盾。
我知道如何使用Reflection
来解决问题,但我正在寻找另一种聪明而巧妙的方法来解决这个问题,而不是使用反射。
我可以自由添加新的Interface
但不能添加基类
任何建议都将受到赞赏
答案 0 :(得分:1)
如果你想保持OPEN / CLOSE原则不变,你可以选择这样的东西 -
Helper
。所以实现变得有点像下面的那个。无论您添加多少个类,每个类都负责自己的Foo
和Bar
实现。 示例 -
public interface IFoo
{
void Foo();
void Bar();
}
public abstract class BaseFoo : IFoo
{
public virtual void Foo()
{
//do nothing
}
public virtual void Bar()
{
//do nothing
}
}
public class A : BaseFoo //replace with IFoo if you do not want the base class, in that case implement both methods
{
IList<B> Bs { get; set; }
IList<C> Cs { get; set; }
public override void Bar()
{
base.Bar();
foreach (var b in Bs)
{
b.Bar();
}
foreach (var c in Cs)
{
c.Bar();
}
}
}
public class B : BaseFoo //replace with IFoo if you do not want the base class, in that case implement both methods
{
IList<D> Ds { get; set; }
public override void Bar()
{
base.Bar();
foreach (var d in Ds)
{
d.Bar();
}
}
}
public class C : BaseFoo //replace with IFoo if you do not want the base class, in that case implement both methods
{
}
public class D : BaseFoo //replace with IFoo if you do not want the base class, in that case implement both methods
{
}
public static class Helper
{
public static void Bar(params IFoo[] foos)
{
foreach (var foo in foos)
{
foo.Bar();
}
}
}
答案 1 :(得分:1)
基于无价的建议和解决方案,我最终如下所示,此解决方案是打开/关闭的,并且只添加另一个列表,只应更改该类以及Bar
类Helper
中的所有重载已移除。
class Program
{
static void Main(string[] args)
{
Helper.Bar(new A());
}
}
public class A : IFoo, IMap
{
public A()
{
Cs = new List<C> { new C(), new C() };
Bs = new List<B> { new B(), new B() };
}
public void Foo()
{
Console.WriteLine("A");
}
public List<B> Bs { get; set; }
public List<C> Cs { get; set; }
public List<Func<dynamic, List<IFoo>>> Map()
{
return this.CreateMap()
.Then(x => ((List<B>)x.Bs).ToList<IFoo>())
.Then(x => ((List<C>)x.Cs).ToList<IFoo>());
}
}
public class B : IFoo, IMap
{
public B()
{
Ds = new List<D> { new D(), new D() };
}
public void Foo()
{
Console.WriteLine("B");
}
public List<Func<dynamic, List<IFoo>>> Map()
{
return this.CreateMap()
.Then(x => ((List<D>)x.Ds).ToList<IFoo>());
}
public List<D> Ds { get; set; }
}
public class C : IFoo, IMap
{
public void Foo()
{
Console.WriteLine("C");
}
public List<Func<dynamic, List<IFoo>>> Map()
{
return this.CreateMap();
}
}
public class D : IFoo, IMap
{
public void Foo()
{
Console.WriteLine("D");
}
public List<Func<dynamic, List<IFoo>>> Map()
{
return this.CreateMap();
}
}
public static class Mapper
{
public static List<Func<dynamic, List<IFoo>>> CreateMap(this IFoo item)
{
return new List<Func<dynamic, List<IFoo>>>();
}
public static List<Func<dynamic, List<IFoo>>> Then(this List<Func<dynamic, List<IFoo>>> list, Func<dynamic, List<IFoo>> expression)
{
list.Add(expression);
return list;
}
}
public class Helper
{
public static void Bar(dynamic obj)
{
obj.Foo();
var map = obj.Map();
if (map != null)
{
foreach(var item in map)
{
var lists = item(obj);
foreach(var list in lists)
{
Bar(list);
}
}
}
}
}
public interface IFoo
{
void Foo();
}
public interface IMap
{
List<Func<dynamic, List<IFoo>>> Map();
}
@ brainlesscoder,@ StuartLC:既然你的解决方案也是正确的,我只会对它们进行投票,并且我没有将任何解决方案标记为保持此线程开放的答案,并且可能有人建议比我们更好的解决方案。如果您认为我的解决方案也很好,请投票;)
答案 2 :(得分:0)
在我看来,这是最直接的方式:
public static class Helper
{
public static void Bar<F>(F f) where F : IFoo
{
f.Foo();
Helper.Bar((f as A)?.Bs);
Helper.Bar((f as A)?.Cs);
Helper.Bar((f as B)?.Ds);
}
public static void Bar<F>(IList<F> fs) where F : IFoo
{
if (fs != null)
{
foreach (var f in fs)
{
Helper.Bar(f);
}
}
}
}
现在,如果代码的其余部分定义如下:
public class A : IFoo
{
public void Foo() { Console.Write("A"); }
public IList<B> Bs { get; set; } = new List<B>() { new B(), new B(), };
public IList<C> Cs { get; set; } = new List<C>() { new C(), new C(), };
}
public class B : IFoo
{
public void Foo() { Console.Write("B"); }
public IList<D> Ds { get; set; } = new List<D>() { new D(), new D(), };
}
public class C : IFoo
{
public void Foo() { Console.Write("C"); }
}
public class D : IFoo
{
public void Foo() { Console.Write("D"); }
}
public interface IFoo
{
void Foo();
}
...然后你可以运行:
var a = new A();
var b = new B();
var c = new C();
var d = new D();
Helper.Bar(a);
Helper.Bar(b);
Helper.Bar(c);
Helper.Bar(d);
...你得到ABDDBDDCCBDDCD
作为输出的预期结果。