【问题标题】:How create a Func<T, bool> when the T is unknown当 T 未知时如何创建 Func<T, bool>
【发布时间】:2016-10-13 21:05:23
【问题描述】:

我有一个对象,他的实例是在运行时创建的,如下所示:

var type = GetTypeFromAssembly(typeName, fullNameSpaceType);
        var instanceOfMyType = Activator.CreateInstance(type);
        ReadObject(instanceOfMyType.GetType().GetProperties(), instanceOfMyType, fullNameSpaceType);
        return instanceOfMyType;

而且我需要通过 Id 找到一个对象,为此我构建了以下方法:

var parameter = Expression.Parameter(typeof(object));

        var condition =
            Expression.Lambda<Func<object, bool>>(
                Expression.Equal(
                    Expression.Property(parameter, theEntity.GetType().GetProperty("Id").Name),
                    Expression.Constant(id, typeof(TKey))
                    ), parameter
                ).Compile();

但是会抛出一个未处理的异常:

没有为类型“System.Object”定义实例属性“Id”

那么,我如何构建一个带有 T 的 Func ,其中 T 是在运行时设置的?像这样的:

var parameter = Expression.Parameter(typeof(MyObjectReflectionRuntimeType>));

        var condition =
            Expression.Lambda<Func<MyObjectReflectionRuntimeType, bool>>(
                Expression.Equal(
                    Expression.Property(parameter, theEntity.GetType().GetProperty("Id").Name),
                    Expression.Constant(id, typeof(TKey))
                    ), parameter
                ).Compile();

更新 [没有实体框架的解决方案]

我做了以下:

    public interface IBaseObject<T>
{
    T Id { get; set; }
}

    public class AnyClass : IBaseObject<Guid>
{
    public Guid Id { get; set; }
}

 var parameter = Expression.Parameter(typeof(IBaseObject<Guid>));
        var id = Guid.NewGuid();
        var theEntity = new AnyClass();

        var theList = new List<AnyClass>
        {
            new AnyClass
            {
                Id = Guid.NewGuid()
            },

            new AnyClass
            {
                Id = Guid.NewGuid()
            },

            new AnyClass
            {
                Id = id
            },

            new AnyClass
            {
                Id = Guid.NewGuid()
            }
        };

        var condition =
            Expression.Lambda<Func<IBaseObject<Guid>, bool>>(
                Expression.Equal(
                    Expression.Property(parameter, theEntity.GetType().GetProperty("Id").Name),
                    Expression.Constant(id, typeof(Guid))
                    ), parameter
                ).Compile();

        var theMetaData = theList.Where(condition).FirstOrDefault();

但它在实体框架上崩溃,因为 IBaseObject&lt;T&gt; 它不是上下文的一部分:( ...

[更新二]

我找到了这样的解决方案,但它不是最佳的(感谢@Serge Semenov):

            var parameter = Expression.Parameter(typeof(object));
        var entity = Expression.Convert(parameter, theEntity.GetType());

        var condition =
            Expression.Lambda<Func<object, bool>>(
                Expression.Equal(
                    Expression.Property(entity, theEntity.GetType().GetProperty("Id").Name),
                    Expression.Constant(id, typeof(TKey))
                    ), parameter
                ).Compile();

        var theObject = await _unitOfWork.Set(theEntity.GetType()).ToListAsync();
        return theObject.FirstOrDefault(condition);

我说这不是最好的方法,因为我想使用 await _unitOfWork.Set(theEntity.GetType()).ToListAsync(); 而不是:await _unitOfWork.Set(theEntity.GetType()).FirstOrDefaultAsync(); 但它不起作用...

有什么想法吗??

【问题讨论】:

  • 可能与use reflection to call generic重复。
  • 我不认为这是该帖子的副本。
  • 不重复...
  • 为什么不将条件作为参数发送?
  • 您希望实现什么目标?能通俗点解释一下吗?

标签: c# lambda


【解决方案1】:

您将object 传递给您的Func&lt;&gt;,但访问在其他类型上定义的Id 属性。

最简单的解决方法是将object 转换为T 类型,然后访问其属性,就像在C# 中所做的((T)obj).Id 一样:

var parameter = Expression.Parameter(typeof(object));
var entity = Expression.Convert(parameter, theEntity.GetType());
...
Expression.Property(entity, theEntity.GetType().GetProperty("Id").Name),
...

【讨论】:

  • 您能否检查一下我对您的建议所做的更新是否如您所愿??
  • 它不起作用,因为object 类型不属于上下文:( ... 这行var theMetaData = _unitOfWork.Set&lt;object&gt;().Where(condition).FirstOrDefault(); 使应用程序崩溃
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-31
  • 1970-01-01
相关资源
最近更新 更多