如何减少这种情况的重复?

时间:2017-01-25 10:22:11

标签: c# generics interface dry

在C#中,我有两个形式为A,A的类,其中A是基于引用类型的自定义IEnumerable,B,C是从类D继承的引用类型。在B,C上存在名为P的属性但不是D,并且将它添加到D是不合适的,因为从D继承的其他类不应该有P.我有A,A的实例b,c我需要为常量x执行以下操作, y与P:

的类型相同
b.Where(v => v.P == x).ForEach(v => v.P = y);
c.Where(v => v.P == x).ForEach(v => v.P = y);

此代码有效,但我怎样才能避免重复。 DRY原则?

我自己的努力遇到了三个主要困难:

  1. 由于P不存在于D上,因此不能简单地创建一个适用于D和cast的实例的函数。 b。选择(v =>(D)v)。

  2. 由于P不存在于泛型类型中,因此编译器不会容忍使用泛型T运行此逻辑的明显方法。

  3. 由于A只取T到哪个类,因此使用A的泛型抱怨T需要是引用类型。

  4. 我特别感兴趣的是在B,C可以继承的新界面上创建通用方法的解决方案,因为我已经建议这种方法应该可行。

3 个答案:

答案 0 :(得分:1)

在我看来,你想解决一个不存在的问题。您的类定义会更简单,但您可以这样做:

class Program
{
    static void Main(string[] args)
    {
        int x = 1;
        int y = 2;

        var b = new MyCustomList<B>();

        b.Foo(v => v.P == x, n => n.P = y);
    }
}

public static class Extensions
{
    public static void Foo<T>(this IFoo<T> @this, Func<T, bool> predicate, Action<T> action) => @this.Where(predicate).ToList().ForEach(action);
}

public interface IFoo<T> : IList<T>  { }

class MyCustomList<T> : List<T>, IFoo<T>  { }

class B
{
    public int P { get; set; }
}

答案 1 :(得分:1)

如果我正确理解你,你需要类似的东西:

public interface IHasPropertyP { Foo P { get; } }
public class B: D, IHasPropertyP { ... }
public class C: D, IHasPropertyP { ... }

List<D> dees = ... //I don't care if the type of the items is B, C or D
var onlyThoseWhoHavePropertyP = dees.OfType<IHasPropertyP>();
onlyThoseWhoHavePropertyP.Where(v => v.P == x).{whatever needs to be done...}

答案 2 :(得分:0)

  

此代码有效,但我怎样才能避免重复。 DRY原则?

可以删除这种重复 - 至少有两种我能想到的方法 - 但考虑一下你在这里得到的东西。你想要执行的操作是“在它是X的那些对象上将P设置为Y” - 这就像它得到的一样简单,并且彼此相邻的两条平行线使得它以一种干燥的方式完全清晰解决方案没有。

我能想到的两种方式已经在其他答案中得到了解释,但简单地说:

  1. 创建一个公共接口Content-Type: text/calendar; charset="utf-8"; method=REQUEST ,然后使methodIHaveAPropertyP实现。需要在BC
  2. 上进行代码更改
  3. 有一个传递任意类型对象的方法,以及B方法和C对该类型对象的属性get的方法。
  4. 无论哪种方式,仍然会有两条非常相似的代码行 - 鉴于此,为什么会变得复杂?