3

我正在尝试使用流利的 nhibernate 创建动态基础映射。

我正在做的是通过 BaseMap< T > 签入: ClassMap< T > if 例如: (typeof(ICategorizedEntity).IsAssignableFrom(typeof(T)))

如果是这样,我想映射一个名为“Category”的属性,它属于 ICategorizedEntity 的接口,但 Map(Func) 函数只接受 T 的属性,所以我试着用 linq 猜测一下,然后想出了这个:

   Expression<Func<ICategorizedEntity, object>> exp = x => x.Category;
   var parameter = Expression.Parameter(typeof (T));
   var lmd = Expression.Lambda<Func<T, object>>(exp, parameter);
   Map(lmd);

这不起作用,因为在“地图”功能的深处,它会检查以下内容:

   MemberExpression memberExpression = (MemberExpression) null;
   if (expression.NodeType == ExpressionType.Convert)
       memberExpression = ((UnaryExpression) expression).Operand as MemberExpression;
   else if (expression.NodeType == ExpressionType.MemberAccess)
       memberExpression = expression as MemberExpression;
   if (enforceCheck && memberExpression == null)
       throw new ArgumentException("Not a member access", "expression");

我得到“不是成员访问\r\n参数名称:表达式”。

如何创建和投射 MemberExpression 或任何类似的东西?

4

2 回答 2

2

Func<DerivedFromT,object>表示接受DerivedFromT参数的方法。Func<T,object>表示接受T参数的方法。通过C# 4 中引入的委托Func<T,object>变体,您可以强制转换为Func<DerivedFromT,object>,但不能反过来(根据您的要求)。

想想这意味着什么:

public class Person { }

public class Student : Person { }

public static class School
{
    public static object Greet(Person person)
    {
        return null; 
    }

    public static object Promote(Student student)
    { 
        return null; 
    }
}

在这种情况下,Greet方法与委托匹配Func<Person,object>,而Promote方法与委托匹配Func<Student,object>

Func<Person, object> greetPerson = School.Greet;
Func<Student, object> promoteStudent = School.Promote;

我们可以Greet转换为Func<Student,object>; 如果我们可以打招呼 a Person,那么我们也可以打招呼 a Student(保证是 的特殊形式Person)。

Func<Student, object> greetStudent = greetPerson;

但是,我们不能Promote转换为Func<Person,object>; 虽然我们可以推广 a Student,但我们一般不能推广任何Person人,除非他/她恰好是 a Student

Func<Person, object> promotePerson = promoteStudent;   // Will not compile.

如果我们知道我们Person是学生,我们可以通过强制转换来表明这一点:

Func<Person, object> promotePerson =
    personWhoIsActuallyStudent => promoteStudent((Student)personWhoIsActuallyStudent);
于 2012-02-10T23:35:59.860 回答
2

谢谢道格拉斯,你引导我找到正确(简单)的答案。

我走得太远试图找到它..

好的旧转换(在 lambda 表达式内)起到了作用:

   Map(x => ((ICategorizedEntity)x).Category);
于 2012-02-11T11:04:00.623 回答