2012-02-10 5 views
2

유창한 nhibernate로 동적 기본 매핑을 만들려고합니다.Func <DerivedFromT, object>에서 Func으로 구성원 액세스 func 캐스팅 <T,object>

내가이 BaseMap에 < T>에 의해 확인됩니다하고 있어요 : ClassMap < T> 예를 들어 같은 경우 (대해서 typeof (ICategorizedEntity) .IsAssignableFrom (대해서 typeof (T)))

그렇다면, I 싶어 ICategorizedEntity의 인터페이스에 속한다 "분류"라는 이름의 속성을 매핑하지만지도 (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 또는 이와 비슷한 작업을 어떻게 만들 수 있습니까?

답변

2

감사합니다 더글러스, 오른쪽 (단순) 대답에 저를지도한다.

나는 (람다 식 내부) .. 그것을 찾기 위해 트릭

그리운 변환 않았다하려고 너무 멀리 갔다 : 당신이 좋은 설명 더글러스에 대한

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

Func<DerivedFromT,object>DerivedFromT 매개 변수를 허용하는 방법을 나타냅니다. Func<T,object>T 매개 변수를 허용하는 메서드를 나타냅니다. C# 4에 도입 된 delegate variance을 통해 Func<T,object>Func<DerivedFromT,object>으로 캐스팅 할 수 있지만 다른 방법으로는 요청할 수 없습니다.

이 무엇을 의미하는지에 대해 생각하십시오 Promote 방법은 위임 Func<Student,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> 일치합니다.

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

우리는 GreetFunc<Student,object>에 전송할 수 있습니다; Person을 접견 할 수 있다면 Student (Person의 특수 형식으로되어 있음)을 환영 할 수 있습니다.

Func<Student, object> greetStudent = greetPerson; 

그러나, 우리는 Func<Person,object>Promote 캐스팅 할 수 없습니다; 우리는 Student을 홍보 할 수 있지만, Student이 아니면 일반적으로 Person을 홍보 할 수 없습니다. 우리는 우리의 Person 학생임을 알고있는 경우

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

, 우리는 그것을 캐스팅하여이를 표시 할 수 있습니다 :

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

감사합니다,하지만 난 당신이 오해 생각 나는 성취하려고 노력했다. 좋은 변환으로 트릭을 만들었습니다. 지도 (x => ((ICategorizedEntity) x) .Category); –

+0

나는 정말 내 질문을 이해하지 못했다는 것을 인정한다. 그래서 내 게시물은 주로 당신의 타이틀을 기반으로했다. 그러나, 나는 아마 당신이 요구 한 in-lambda 캐스팅을 수행하는 코드의 마지막 줄에 대답이 있다고 가정했다. – Douglas

+0

네, 저에게 답을주었습니다. –

관련 문제