2017-11-02 3 views
-1

저는이 일반적인 개념에 대해 반복적으로 고심하고 있으므로 다가 가야 할 때입니다.런타임 생성 위임자 및 객체 사용

MyDataContext context = new MyDataContext(); 
var list = (
    from t in context.GetTable<FooTable>() 
    where t.FooType = userProvidedString 
    select t.SomeColumn).ToList() 
     .Select(colValue => MyClass.FromString(colVal)) 
     .ToList(); 
int unique = list.Distinct(new MyClassComparer()).Count(); 

나는를 사용하는 다른 "프로파일"의 소수를 가지고 : 나는 다음 선택 호출하고 문자열을 섭취 정적 메서드를 제공하고 개체를 반환, SQL에서 문자열 목록을 선택하는 LINQ 쿼리를 동일한 쿼리이지만 다른 유형이 있습니다. 예를 들어, MyClass 외에도 MyOtherClass에는 문자열 매개 변수를 사용하지만 자체 인스턴스를 반환하는 FromString 메서드가 있습니다. 쿼리에서 목록을 가져온 후에는 런타임시 다시 결정되는 비교 자 대리자를 제공하여 Distinct를 호출하려고합니다.

내가 항상 이런 종류의 문제를 겪는 문제는 빌드시 유형입니다. 나는이 같은 비교자를 만들 수 있습니다 알고

Type comparerType = Type.GetType(String.Format("MyNamespace.{0}Comparer", userProvidedString)); 
ConstructorInfo ctor = comparerType.GetConstructor(new Type[] { }); 

을하지만이의 ctor에 호출을 호출 할 때, 나는 아직도 캐스트 할 수있는 객체로 끝날. 나는 이것이 할 수 있고, 나는 단지 핵심 개념이 빠져 있다는 것을 확신한다. 주현절을 보내주세요! 미리 감사드립니다 ...

+2

_ "이 작업을 수행 할 수 있습니다."- 할 수있는 작업이 확실합니까? 귀하의 질문은 매우 불분명합니다. 처음에 비교자를 만들기 위해 리플렉션을 사용하는 이유는 무엇입니까? 리플렉션을 사용한다고 가정 할 때 리플렉션 API가 새로 작성한 객체에 강력한 형식의 참조를 반환하는 방법이있을 것이라고 생각하는 이유는 무엇입니까? 리플렉션 API는 생성하는 객체의 유형을 선험적으로 어떻게 알 수 있습니까? 당신이 묻고있는 것을 분명하게 보여주는 좋은 [mcve]를 제공해주십시오. _precisely_ 코드가 지금하고있는 일과 원하는 것을 설명하십시오. –

+1

그냥 함수에서 이것을 랩핑하고 변환기/비교자를 전달할 수 없습니까? 즉'Func '&'IConparer 'params – James

+0

위의 두 가지 의견에 동의합니다. - 여러분은 단지'IComparer '을 받아들이고 반환 할 Factory 메소드를 가지기 위해'Distinct()'메소드를 작성하는 것처럼 보입니다. 적절한 상황에 대한 예? 예 : 반사는 필요하지 않습니다. – zaitsman

답변

0

"건설적인 의견"은 저를 올바른 방향으로 이끌었고, 제가 생각해 냈습니다.

public void Foo() 
{ 
    string dataType = "MyClass"; // Pretend this string was specified by the user 
    Type t = Type.GetType(dataType); 
    Type u = Type.GetType(dataType + "Comparer"); // Implements IEqualityComparer<MyClass> 
    MethodInfo method = this.GetType().GetMethod("GetUniqueItemCount", BindingFlags.Instance | BindingFlags.NonPublic); 
    MethodInfo generic = method.MakeGenericMethod(t, u); 

    int count = (int)generic.Invoke(this, new object[] { "some data blah blah" }); 
} 

private void GetUniqueItemCount<T, U>(string data) where T : class 
                where U : IEqualityComparer<T>, new() 
{ 
    MyDataContext context = new MyDataContext(); 
    var list = (
     from v in context.GetTable<SomeTable>() 
     select v.SomeColumn).ToList() 
      .Select(cellValue => Activator.CreateInstance(typeof(T), new object[] { cellValue }) as T) 
      .ToList(); 
    return list.Distinct(new U()).Count(); 
} 

유감스럽게도, 나는 "새로운 T는()"만 매개 변수가없는 생성자를 사용할 수 있기 때문에 Activator.CreateInstance로를 사용했다. 이는 쿼리 결과 집합의 각 항목에 대해 호출되므로 좋지 않습니다.

내가 T와 U를 만들고 메소드를 호출 한 모든 반사물은 내가 내 질문에서 언급 한 것입니다. (피하기를 희망합니다.) 이 솔루션은 내 의도를 여기에 완전히 설명해야하므로 더 깨끗한 접근 방법을 알고 있다면 차임하십시오.

도움을 다시 한번 감사드립니다!