Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert Type parameter to T

I'm a little stumped on how to pass in a type argument to a Method, from a parameter.

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);

        ...........

I've tried the following, but these fail as well;

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

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

Obviously this compiles, but makes little sense;

XElement xmloutput = XElementSerialiser.ToXElement<Type>(value);
like image 598
wonea Avatar asked Dec 19 '25 04:12

wonea


1 Answers

Generic instantiation (i.e. adding <T> to signature) is a compile-time construct, while Type object exists at runtime.

It would be preferable, as D Stanley suggested, to make the whole method generic and not pass a Type object at all.
However, if you're unable to do that, you can make yourself a generic factory with non-generic interface, and create instances of it dynamically. Like so:

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 );
}

For performance reasons, you might also want to cache the factory instance.

UPDATE: made a blog post out of it.

like image 183
Fyodor Soikin Avatar answered Dec 20 '25 22:12

Fyodor Soikin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!