у меня 2 IEnumerable<decimal>
.например, {0,0.1,0.5,1}
и {a,b,c,d}
предполагают равную длину
Пример кода объекта домена:
public class Foo //does not implement IEnumerable because nothing outside of itself should treat it as such
{
private readonly decimal _a;
private readonly decimal _b;
private readonly decimal _c;
//another class also has private readonly decimal _d;
public decimal A {get{return _a;}}
//...
public decimal C {get{return _c;}}
}
Я хочу определить Foo1>Foo2
- , если всевстретить
>=
(как в Foo1.A>=Foo2.A && ' .. 'Foo1.C>=Foo2.C
..) - Как минимум один
>
(как в Foo1.B>Foo2.B
)
Пример итерационного кода:
//DRY violation, but probably the shortest route to the goal
private static IEnumerable<Func<Foo,decimal>> Accessors=
new List{f=>f.A,f=>f.B,f=>f.C};
public static bool operator>(Foo foo1, Foo foo2)
{
if (foo1==null||foo2==null)
return false;
bool foundGreater=false;
foreach (var accessor in _Accessors)
{
if (accessor(foo1)<accessor(foo2))
return false;
if (foundGreater==false&&accessor(foo1)>accessor(foo2))
foundGreater=true;
}
return foundGreater;
}
информация и ответы, включающие zip, приветствуются с точки зрения обучения, так как они атакуют всю проблему переменных длин свойств, используя те же функции сравнения, которые не требуют отражения.
Однако в настоящее время я нахожусьработа в рамках .net 2.0 с LinqBridge.
Я рассматриваю что-то вроде следующего, чтобы охватить все классы, которым требуется одинаковая функциональность
//Needs a better name for sure
public static bool AllWithAny<T,TValue>(IEnumerable<Func<T,TValue>> accessors,T item1, T item2,
Func<TValue,TValue,bool> shortCircuitBreak,Func<TValue,TValue,bool> atLeastOneCondition)
{
GuardStrategy.ThrowIfNull(accessors,"accessors");
GuardStrategy.ThrowIfNull(item1, "item1");
GuardStrategy.ThrowIfNull(item2, "item2");
var foundOne=false;
foreach(var accessor in accessors)
{
var values=new {Value1=accessor(item1),Value2=accessor(item2)};
if (shortCircuitBreak(values.Value1, values.Value2))
return false;
if(foundOne==false && atLeastOneCondition(values.Value1,values.Value2))
{
foundOne=true;
}
}
return foundOne;
}
Вопрос (ы):
Существует ли существующая комбинация ключевых слов / операторов Linq, которая сделает все это более изящно?Есть ли более элегантный / более простой способ сделать этот тип сравнения, который лучше DRY, меньше кодирования и больше повторного использования?