使用来自表达式>的信息创建运行时谓词

本文关键字:信息 创建 谓词 运行时 对象 表达式 Func | 更新日期: 2023-09-27 18:34:49

>假设以下代码

private readonly T entity;
public bool HasUnique<T>(Expression<Func<T, object>> property, IEnumerable<T> entities)
{
}

其中property是实体T的属性表达式。

如何检查entities中是否有任何元素具有与entity相同的属性值,而属性是从给定的属性表达式解析的?

到目前为止,我可以从实体中获取属性名称及其值

问题似乎是如何在运行时设置和执行谓词?类似的东西

Func<T, bool> predicate = // build a predicate
var isUnique = !entities.Any(predicate);

用法是这样的

var isUnique = HasUnique<Person>(p => p.Name, people);

使用来自表达式<Func<T、对象>>的信息创建运行时谓词

我试图弄清楚"独特"这个词与您描述的内容有什么关系,并且您的示例用法不涉及任何实体来比较people的内容,但我认为您要这样的东西?

public static bool HasUnique<T>(this T referenceItem, Func<T, object> property, 
                                IEnumerable<T> entities)
{
    var referenceProperty = property(referenceItem);
    return entities.Any(e => property(e) == referenceProperty);
}

或者也许是这个:

public static bool HasUnique<T>(this T referenceItem, Func<T, object> property, 
                                IEnumerable<T> entities)
{
    var referenceProperty = property(referenceItem);
    return entities.Any(e => property(e).Equals(referenceProperty));
}

甚至这个:

public static bool HasUnique<T, TProp>(this T referenceItem, Func<T, TProp> property, 
                                IEnumerable<T> entities)
{
    var referenceProperty = property(referenceItem);
    return entities.Any(e => property(e).Equals(referenceProperty));
}

你需要Expression<Func<T,object>>吗?因为它只需Func<T,object>即可实现.

using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqPlayground
{
    class Program
    {
        public class UniqueChecker<T>
        {
            public bool HasUnique<T>(Func<T, object> property, IEnumerable<T> entities)
            {
                var uniqueDict = new Dictionary<object, bool>();
                foreach (var entity1 in entities)
                {
                    var key = property(entity1);
                    if (uniqueDict.ContainsKey(key))
                    {
                        uniqueDict[key] = false;
                    }
                    else
                    {
                        uniqueDict.Add(key, true);
                    }
                }
                return uniqueDict.Values.All(b => b);
            }
        }
        public class Person
        {
            public string Name { get; set; }
        }
        static void Main(string[] args)
        {
            var people = new List<Person>
            {
                new Person {Name = "Chris"},
                new Person {Name = "Janet"},
                new Person {Name = "John"},
                new Person {Name = "Janet"},
            };
            var checker = new UniqueChecker<Person>();

            Console.WriteLine("Are names unique? {0}",checker.HasUnique(person => person.Name, people));
        }
    }
}