从func<;派生自T,对象>;到Func<;T、 对象>;

本文关键字:gt 对象 lt Func func 派生 | 更新日期: 2023-09-27 18:24:00

我正在尝试使用fluent nhibernate创建一个动态基映射。

我正在做的是通过BaseMap<T>:ClassMap<T>例如:(类型为(ICategorizedEntity).IsAssignableFrom(类型为)(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或任何类似的内容?

从func<;派生自T,对象>;到Func<;T、 对象>;

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>;如果我们可以问候一个Person,那么我们也可以问候Student(他保证是Person的特殊形式)。

Func<Student, object> greetStudent = greetPerson;

但是,我们不能将Promote强制转换为Func<Person,object>;尽管我们可以推广Student,但我们通常不能推广任何Person,除非他/她碰巧是Student

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

如果我们知道我们的Person是一名学生,我们可以通过铸造它来表明这一点:

Func<Person, object> promotePerson =
    personWhoIsActuallyStudent => promoteStudent((Student)personWhoIsActuallyStudent);

谢谢Douglas,你让我找到了正确的(简单的)答案。

我找它太远了。

好的旧转换(在lambda表达式中)做到了:

   Map(x => ((ICategorizedEntity)x).Category);