2016-12-05 3 views
1

을 필요로 클래스 getMethod 메소드에 사용하는 것은 희망으로 여전히 쟁점으로 남아 점을 해결하기 위해 몇 가지 추가 정보입니다올바른 서명이 여러 과부하 일반적인 방법은 여기 부분에 질문을 수행 답변에 따라 위임 인수

시작 편집

내가 첫 번째 대답에 표시 같은 방법으로 closeMethod.Invoke을 사용할 수 없습니다 염두에두고

var curEntityPI = ctx.GetType().GetProperties().Where(pr => pr.Name == "Client").First(); Type curEntityType = curEntityPI.PropertyType.GetGenericArguments().First(); Type[] typeArgs = { curEntityType }; Type propertyManagerType = generic.MakeGenericType(typeArgs); var propertyManager = Activator.CreateInstance(propertyManagerType, new object[] {});

그것은 호출 할 때 나는 장소에 배치하는 방법을 모르는 Func을 반환 몸

최종 편집

, 나는 http://putridparrot.com/blog/dynamically-extending-an-objects-properties-using-typedescriptor/

    여기이 클래스에이

    DynamicPropertyManager<ThreeColumns>.CreateProperty<ThreeColumns, string>(
        "Four", 
        t => "Four", 
        null 
    )); 
    

    의 동등한를 호출 반사에 같은 방법 서명 모양 시도하고해야합니까

  1. 하지만 리플렉션을 사용하여이를 수행하려고합니다. 으로 고심하고있는 무엇이 정확한 방법 과부하를 얻고있다.

  2. 반사를 통해 람다 비트에 대한 올바른 인수를 제공하는 방법에 대해서도 완전히 확신 할 수는 없지만 솔직히 말해야합니다. 중 하나입니다.

나는 부분이 시도 거라고하지만 FUNC 비트 이
Func<string> funcArg =() => { return "Four"; }; 

object[] args = { fieldOrPropertyName , funcArg, null }을 MakeGenericMethod

을 할 때 어떻게 보이는지 모른다;

위 링크의 수업 내용은 참조 용으로 포함되어 있습니다.

public class DynamicPropertyManager<TTarget> : IDisposable 
{ 
    private readonly DynamicTypeDescriptionProvider provider; 
    private readonly TTarget target; 

    public DynamicPropertyManager() 
    { 
     Type type = typeof(TTarget); 

     provider = new DynamicTypeDescriptionProvider(type); 
     TypeDescriptor.AddProvider(provider, type); 
    } 

    public DynamicPropertyManager(TTarget target) 
    { 
     this.target = target; 

     provider = new DynamicTypeDescriptionProvider(typeof(TTarget)); 
     TypeDescriptor.AddProvider(provider, target); 
    } 

    public IList<PropertyDescriptor> Properties 
    { 
     get { return provider.Properties; } 
    } 

    public void Dispose() 
    { 
     if (ReferenceEquals(target, null)) 
     { 
      TypeDescriptor.RemoveProvider(provider, typeof(TTarget)); 
     } 
     else 
     { 
      TypeDescriptor.RemoveProvider(provider, target); 
     } 
    } 

    public static DynamicPropertyDescriptor<TTargetType, TPropertyType> 
     CreateProperty<TTargetType, TPropertyType>(
      string displayName, 
      Func<TTargetType, TPropertyType> getter, 
      Action<TTargetType, TPropertyType> setter, 
      Attribute[] attributes) 
    { 
     return new DynamicPropertyDescriptor<TTargetType, TPropertyType>(
      displayName, getter, setter, attributes); 
    } 

    public static DynamicPropertyDescriptor<TTargetType, TPropertyType> 
     CreateProperty1<TTargetType, TPropertyType>(
      string displayName, 
      Func<TTargetType, TPropertyType> getHandler, 
      Attribute[] attributes) 
    { 
     return new DynamicPropertyDescriptor<TTargetType, TPropertyType>(
      displayName, getHandler, (t, p) => { }, attributes); 
    } 

    public static DynamicPropertyDescriptor<TTargetType, TPropertyType> 
     CreateProperty<TTargetType, TPropertyType>(
      string displayName, 
      Func<TTargetType, TPropertyType> getHandler, 
      Attribute[] attributes) 
    { 
     return new DynamicPropertyDescriptor<TTargetType, TPropertyType>(
      displayName, getHandler, (t, p) => { }, attributes); 
    } 
} 

답변

1

반사 및 제네릭 때문에 아마도, 폐쇄 개방적이고 부분적으로 폐쇄 유형과 방법, 어떻게 특정 목표에 접근하는 매우 문맥에 의존 함께 매우 잘 작동되지만. 그럼에도 불구하고 종종 Linq를 사용하여 찾고있는 것을 얻는 것이 쉽습니다. 보라 :

// get type from somewhere 
var compileTimeUnknownType = Type.GetType("ThreeColumns"); 

if (compileTimeUnknownType == null) 
    throw new ArgumentException("compileTimeUnknownType"); 

var managerType = typeof (DynamicPropertyManager<>).MakeGenericType(compileTimeUnknownType); 

var createPropertyMethod = managerType.GetMethods().Single(x => 
{ 
    var p = x.GetParameters(); 
    var g = x.GetGenericArguments(); 
    return x.Name == "CreateProperty" && 
      p.Length == 3 && 
      g.Length == 2 && 
      p[0].ParameterType == typeof (string) && 
      p[1].ParameterType == typeof (Func<,>).MakeGenericType(g) && 
      p[2].ParameterType == typeof (Attribute[]); 
}); 

var closedMethod = createPropertyMethod.MakeGenericMethod(new[] {compileTimeUnknownType, typeof (string)}); 

var paramExpr = Expression.Parameter(compileTimeUnknownType, "arg"); 
var lambda = 
    Expression.Lambda(typeof (Func<,>).MakeGenericType(new[] {compileTimeUnknownType, typeof (string)}), 
     Expression.Constant("Four"), new List<ParameterExpression>() {paramExpr}).Compile(); 

var ret = closedMethod.Invoke(null, new object[] {"Four", lambda, null}); 
+0

안녕 덕분에 대규모 답장을 보내 나는 createPropertyMethod가 잘 작동합니다 생각하지만, 내가 가지고있는 문제는 반사를 사용하고있는 이유는 ThreeColumns 클래스는 런타임 때까지 나에게 알 수 없다는 점이다. 내 경우에는 속성을 첨부 할 클래스가 실제로 리플렉션을 통해 얻은 다른 일반 클래스이고 다음 클래스 유형으로 propertymanager 인스턴스를 인스턴스화합니다. –

+0

코드를 수정했으며 이제는 'ThreeColumns' 유형이 컴파일되지 않습니다. 더 이상 참조 된 시간. – thehennyy

+0

정말 고마워요. 나는 그것을 줄 것이고 받아들이고 투표 할 것이다. 당신의 대답. 당신은 정말로 생명의 은인이되었습니다 –