2014-05-15 2 views
3

매개 변수에서 형식 인수를 메서드로 전달하는 방법이 약간 잘못되었습니다.형식 매개 변수를 T로 변환

public class MyNamespaceXmlFormatter : XmlMediaTypeFormatter 
{ 
    public override Task WriteToStreamAsync(Type type, object value, 
              Stream writeStream, HttpContent content, 
              TransportContext transportContext, System.Threading.CancellationToken cancellationToken) 
    { 
     XElement xmloutput = XElementSerialiser.ToXElement<type>(value); 

     ........... 

나는 다음을 시도했지만 역시 실패합니다.

XElement xmloutput = XElementSerialiser.ToXElement<(T)type>(value); 

XElement xmloutput = XElementSerialiser.ToXElement<typeof(type)>(value); 

분명히 컴파일되지만 의미가 없습니다.

XElement xmloutput = XElementSerialiser.ToXElement<Type>(value); 

답변

7

일반 인스턴스 Type 객체가 런타임에 존재하는 동안 (서명 <T>를 추가하는 예), 컴파일시 구조입니다.

D Stanley가 제안한 것처럼 전체 메서드를 일반화하고 Type 개체를 전혀 전달하지 않는 것이 좋습니다.
그러나 그렇게 할 수 없다면, 비 제네릭 인터페이스가있는 제네릭 팩토리로 만들고 인스턴스를 동적으로 만들 수 있습니다. 그래서 같이 : 성능상의 이유로

interface IFactory { 
    XElement ToXElement(object value); 
} 

class Factory<T> : IFactory { 
    public XElement ToXElement(object value) { 
     return XElementSerialiser.ToXElement<T>(value); 
    } 
} 

public override Task WriteToStreamAsync(Type type, object value, 
            Stream writeStream, HttpContent content, 
            TransportContext transportContext, System.Threading.CancellationToken cancellationToken) { 
    var factory = Activator.CreateInstance(typeof(Factory<>).MakeGenericType(type)) as IFactory; 
    return factory.ToXElement(value); 
} 

, 당신은 또한 factory 인스턴스를 캐시 할 수 있습니다.

업데이트 :blog post입니다.

+0

유감스럽게도, 이것은 당신이 타입 인자를 취하는 정적 메소드에서 일반적인 정적 메소드를 호출하려고하는 단순한 경우 오버 헤드가 많이 발생한다. 블로그 게시물. –

+0

무엇보다 오버 헤드가 너무 많습니까? –

+0

여분의 클래스 측면에서 많은 오버 헤드가 작성되고 인스턴스화되고 잠재적으로 캐시되어야합니다. 나는 확실히 이것이 나쁜 해결책이라고 말하지 않고있다. 일반적인 것에서 비 제네릭 메서드를 호출하는 것과 같은 간단한 일을하는 것이 좋을 것이다. (반대로, 사소한 것에 비해) ... 잘, 단순한. –

4

당신 이 제네릭을 사용 할 수 있지만, 대신 WriteToStreamAsync 일반적인 만들 수 있을까? 그래서 당신이 그것을 당신이 방법이 사용 사용할 때마다 지정할 필요가 없습니다

public override Task WriteToStreamAsync<T>(object value, 
             Stream writeStream, HttpContent content, 
             TransportContext transportContext, System.Threading.CancellationToken cancellationToken) 
{ 
    XElement xmloutput = XElementSerialiser.ToXElement<T>(value); 
+1

나는 그것이 System.Net.Http.Formatting.MediaTypeFormatter'에서 무언가를 무시하는 것처럼 보였으므로 옵션이 아닐 수도 있습니다 ... – Chris

+1

좋은 점, 명확하게하기 위해 제 질문을 수정했습니다. – wonea

0

나는 D 스탠리의 대답에 동의하지만, 경우에 당신은 컴파일러는 객체의 유형이 당신을 위해 직렬화되는 추론 갖고 싶어 :

public override Task WriteToStreamAsync<T>(T value, 
             Stream writeStream, HttpContent content, 
             TransportContext transportContext, System.Threading.CancellationToken cancellationToken) 
{ 
    XElement xmloutput = XElementSerialiser.ToXElement<T>(value); 
+1

예, 메소드를 오버로드 할 수는 있지만 형식을 T로 변환해야합니다. – wonea

+0

더 이상'Type'을 넘겨 줄 필요가 없습니다. 그것은 당신을 위해 컴파일러에 의해 추측됩니다. 'WriteToStreamAsync (serializeThis, stream, ...) '을 호출하기 만하면된다. –

관련 문제