Lizzard
Lizzard

Reputation: 193

Setting Generics on the Fly

I have a question with generics, and think this may be impossible but thought Id throw it out there in hopes of finding some sort of solution. I have an object that uses generics, I want to set the generic on the fly. My problem is, or the reason why reflection can only get me so far, is that the object needs to be sent into a method as an out param. Any suggestions? The code is below

GetConfigurationSettingMessageResponse<DYNAMICALLYSETTHIS> ch;
if (MessagingClient.SendSingleMessage(request, out ch))
{
    if (ch.ConfigurationData != null)
    {
        data = ch.ConfigurationData;
    }
}

Upvotes: 0

Views: 495

Answers (3)

IanNorton
IanNorton

Reputation: 7282

EDITED: Essentially, you need to pass in a reference to a type you can't know at compile time. In which case we need to defeat the compile time checking with reflection.

using System.Reflection;

public class ResponseWrapper {

  public static ConfigurationData GetConfiguration( Request request, Type dtype  )
  {
    // build the type at runtime
    Type chtype = typeof(GetConfigurationSettingMessgeResponse<>);
    Type gchtype = chtype.MakeGenericType( new Type[] { dtype } );

    // create an instance. Note, you'll have to know about your 
    // constructor args in advance. If the consturctor has no 
    // args, use Activator.CreateIntsance.

    // new GetConfigurationSettingMessageResponse<gchtype>
    object ch = Activator.CreateInstance(gchtype); 


    // now invoke SendSingleMessage ( assuming MessagingClient is a 
    // static class - hence first argument is null. 
    // now pass in a reference to our ch object.
    MethodInfo sendsingle = typeof(MessagingClient).GetMethod("SendSingleMessage");        
    sendsingle.Invoke( null, new object[] { request, ref ch } );

    // we've successfulled made the call.  Now return ConfigurtationData

    // find the property using our generic type
    PropertyInfo chcd = gchtype.GetProperty("ConfigurationData");
    // call the getter.
    object data = chcd.GetValue( ch, null );

    // cast and return data
    return data as ConfigurationData;


  }

}

Once you've done this, you could create a helper method to let you maniupulate the ch object instead of the GetProperty part.

Upvotes: 0

jbtule
jbtule

Reputation: 31799

How about make a generic convenience method and then use reflection to call it.

void HelperMethod<TType>(){
    GetConfigurationSettingMessageResponse<TType> ch;
    if (MessagingClient.SendSingleMessage(request, out ch))
    {
        ... //Do your stuff.
    }

}

Upvotes: 1

Carlos P
Carlos P

Reputation: 3989

More of a workaround than a direct answer, but do you have to write the code so strongly typed? Perhaps you leave it as an GetConfigurationSettingMessageResponse<object> and test at a later stage to see what it is:

void SendSingleMessage(int request, out GetConfigurationSettingMessageResponse<object> obj)
{
    if (obj.InnerObject is Class1)
    {...}
    else if...
..
}

...

   class GetConfigurationSettingMessageResponse<T>
    {
        public T _innerObject { get; set; }
    }

Upvotes: 0

Related Questions