Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用用户定义的条件查询对象集合?_C#_Collections_Conditional Statements_User Defined - Fatal编程技术网

C# 如何使用用户定义的条件查询对象集合?

C# 如何使用用户定义的条件查询对象集合?,c#,collections,conditional-statements,user-defined,C#,Collections,Conditional Statements,User Defined,抱歉,这有点抽象。我正处于发展的早期阶段 我有两种对象类型: 需要存储一系列用户定义条件的对象。 与第一个对象中定义的零个或多个条件相匹配的对象。 下面是一个简单的示例,说明它将如何运行 用户创建多个类型为2的对象并将其添加到集合中。 然后,用户创建类型为1的对象,并为其指定若干条件。 系统使用对象类型1中的条件生成类型2的对象列表,按每个对象匹配的条件百分比排序。 以下是预期输出的示例: Conditions

抱歉,这有点抽象。我正处于发展的早期阶段

我有两种对象类型:

需要存储一系列用户定义条件的对象。 与第一个对象中定义的零个或多个条件相匹配的对象。 下面是一个简单的示例,说明它将如何运行

用户创建多个类型为2的对象并将其添加到集合中。 然后,用户创建类型为1的对象,并为其指定若干条件。 系统使用对象类型1中的条件生成类型2的对象列表,按每个对象匹配的条件百分比排序。 以下是预期输出的示例:

Conditions                                            List
Quantity >= 2                                         Object5 100%
Value < 2                                             Object2  75%
Category = "Blah"                                     Object4  50%
Quality > 5                                           Object1  25%
                                                      Object3   0%
每个条件中的第一个操作数是属性的名称,而第二个操作数是该属性的值

我怎样才能做到这一点


我的第一个想法是,它看起来类似于查询语言。如果它们是DB表中的记录,我可以为每个条件缝合一个SQL字符串,运行每个查询并计算每个记录id在查询结果中出现的次数。但这些都是普通的旧C对象。我还没有决定使用什么来实现对象持久性,所以我现在不想把自己绑定到db引擎上。有什么建议吗?

这听起来像是你想要使用的。特别是,我将研究是否最终选择了持久性存储


下面是使用LINQ到字符串上的对象的示例实现:

var conditions = new Func<string, bool>[]
{
    s => s.Length < 4,                  // less than 4 characters
    s => s.Count(c => c == 'o') > 2,    // more than 2 'o's
    s => s == "fooo",                   // is "fooo"
    s => s.Contains('b'),               // contains 'b'
};
var words = new[] { "foo", "fooo", "foooo", "bar", "barr", "bazooo" };
var query = words.Select(Word => new
                                 {
                                     Word,
                                     Percentage = conditions.Average(c => c(Word) ? 1M : 0M)
                                 })
                 .Where(p => p.Percentage > 0)          // keep words matches some conditions
                 .OrderByDescending(p => p.Percentage)  // order by the percentage
                 .ThenBy(p => p.Word);                  // then order in alphabetical order
回想起来,我认为这个例子可能也适用于LINQtoSQL,并对conditions数组进行了一些调整


这只是一个简单的例子,但您当然可以进一步扩展这个想法。

您可以通过修改版本的。从一个将结果表示为百分比的界面开始:

public interface ISpecification<T>
{
    double GetPercentSatisfiedBy(T target);
}
此设计支持任意复杂度的规范

public interface ISpecification<T>
{
    double GetPercentSatisfiedBy(T target);
}
public sealed class Specification<T> : ISpecification<T>
{
    private readonly Func<T, bool> _predicate;

    public Specification(Func<T, bool> predicate)
    {
        _predicate = predicate;
    }

    public double GetPercentSatisfiedBy(T target)
    {
        return _predicate(target) ? 1 : 0;
    }
}
public sealed class CompositeSpecification<T> : ISpecification<T>
{
    private readonly IList<ISpecification<T>> _specifications;

    public CompositeSpecification(params ISpecification<T>[] specifications)
    {
        _specifications = specifications.ToList();
    }

    public double GetPercentSatisfiedBy(T target)
    {
        return _specifications.Average(
            specification => specification.GetPercentSatisfiedBy(target));
    }
}
var specification = new CompositeSpecification<Foo>(
    new Specification<Foo>(foo => foo.Quantity >= 2),
    new Specification<Foo>(foo => foo.Value < 2),
    new Specification<Foo>(foo => foo.Category == "Blah"),
    new Specification<Foo>(foo => foo.Quality > 5));

var foos = new List<Foo> { ... };

var results =
    from foo in foos
    let percentSatisfied = specification.GetPercentSatisfiedBy(foo)
    orderby percentSatisfied descending
    select new
    {
        Foo = foo,
        PercentSatisfied = percentSatisfied
    };