3

流暢な nhibernate を使用して動的ベース マッピングを作成しようとしています。

私がやっていることは、 BaseMap< T > : ClassMap< T > によるチェックインです。たとえば、 (typeof(ICategorizedEntity).IsAssignableFrom(typeof(T)))

もしそうなら、ICategorizedEntity のインターフェイスに属する「Category」という名前のプロパティをマップしたいのですが、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);

「Map」関数の奥深くで次のことをチェックするため、これは機能しません。

   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

ありがとうダグラス、あなたは私を正しい(単純な)答えに導いてくれました。

探しに行き過ぎた..

古き良き変換(ラムダ式内)がうまくいきました:

   Map(x => ((ICategorizedEntity)x).Category);
于 2012-02-11T11:04:00.623 に答える
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>。に挨拶できる場合は、 (の特殊な形式であることが保証されている)にPerson挨拶することもできます。StudentPerson

Func<Student, object> greetStudent = greetPerson;

ただし、にキャストPromoteすることはできませんFunc<Person,object>。を昇格させることはできますが、たまたま が である場合を除き、一般的にStudentは昇進させることはできません。PersonStudent

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

Person自分が学生であることがわかっている場合は、キャストしてこれを示すことができます。

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