3

I have an object that is passed to me as ISomething. I need to serialize the object however my serilizer expects a type parameter of a concrete type i.e:

string xml = Utilities.Serialize<ConcreteType>(myObject);

Basically I want to to the same thing as this guy: Creating a generic object based on a Type variable

however I dont want to create a new instance of an object I want to use the resulting type as a parameter to my generic class.

So my question in a nutshell is how do I create some variable that represents the concrete type of some object that I can use with a generic class like this:

string xml = Utilities.Serialize<ConcreteType>(myObject);

where ConcreteType is what I need to create.

Community
  • 1
  • 1
Sam
  • 1,621
  • 3
  • 22
  • 30
  • I'm not familiar with Utilities.Serialize in .net. Could you perhaps comment on the full name (all namespaces)? – CrazyCasta Oct 01 '12 at 21:57
  • @CrazyCasta: It doesn't really matter. What the OP needs is `Utilities.SomeMethod(myObject)` – Robert Harvey Oct 01 '12 at 22:00
  • It is irrelevant I'm just using it as an example. To clarify, I may want to make a List where T is the concrete type per my question. – Sam Oct 01 '12 at 22:01
  • So he wants to call a method with a generic type specified by a variable? Seems a lot easier to just use ISerialize. – CrazyCasta Oct 01 '12 at 22:02
  • 2
    Why exactly is `Serialize()` generic? There doesn't seem to be a good reason for that. If the type really is necessary, maybe an overload that takes `Type` as normal parameter would be better. – svick Oct 01 '12 at 22:03
  • You can't specify `` at runtime, unless you want to attempt to [call the methods via reflection](http://stackoverflow.com/a/2107864/102937). If you want runtime flexibility, you need a new method that's not generic, as @svick states. – Robert Harvey Oct 01 '12 at 22:28

4 Answers4

4

So let's say you've got something like:

public static class Util
{
    public static T Foo<T>(object obj)
    {
         // Do actual stuff here
         return default(T);
    }
}

Normally, the compiler would wire up any usage of this method, swapping in the appropriate generic variant based on what you passed it. We no longer can rely on the compiler if you have a variable containing the Type - but we can ask the class to give us the variant we want:

public void DoFooWith(object blob)
{
    // Get the containing class
    var utilType = typeof(Util);
    // Get the method we want to invoke
    var baseMethod = utilType.GetMethod("Foo", new Type[]{typeof(object)});
    // Get a "type-specific" variant
    var typedForBlob = baseMethod.MakeGenericMethod(blob.GetType());
    // And invoke it
    var res = typedForBlob.Invoke(null, new[]{blob});
}
JerKimball
  • 16,584
  • 3
  • 43
  • 55
0

If you absolutely need to get the type of the actual object you can use GetType(). The problem is, you will have to call all your functions using reflection because as far as I know there no easy way to call them with a variable with the type.

CrazyCasta
  • 26,917
  • 4
  • 45
  • 72
0

You can not guarantee that all ISomething's are ConcreteType's but you can cast them and pass on the ones that work.

string CastAndSerialize(ISomething somthing)
{
    //castSomthing will be null if ISomthing was not a ConcreteType.    
    ConcreteType castSomthing = somthing as ConcreteType; 

    if(castSomthing != null)
    {
       return Utilities.Serialize<ConcreteType>(castSomthing );
    }
    else
    {
        return null; //Or whatever you want to use to represent that the cast failed.
    }
}

Here is a more generic version, this will work with anything that is a class.

string CastAndSerialize<T>(ISomething somthing) where T : class
{ 
    T castSomthing = somthing as T; 

    if(castSomthing != null)
    {
       return Utilities.Serialize<T>(castSomthing );
    }
    else
    {
        return null;
    }
}
Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
-2

Could be a case for another form of generic method. If you own Utilities.Serialize(...) and can generate a new overload, take a look at:

http://msdn.microsoft.com/en-US/library/twcad0zb(v=VS.80).aspx

For example:

string Utilities.Serialize<T>(T object) 
    where T : ConcreteType

Upon further reflection (pun intended) could the following be what you are looking for?

Calling a generic method with a dynamic type

Community
  • 1
  • 1
Jace
  • 1,445
  • 9
  • 20
  • The method already is generic, the question is how to call it in this case. – svick Oct 01 '12 at 22:04
  • Wow, harsh. My line of thinking was instead of: Utilities.Serialize(myObject); do something like: Utilities.Serialize(T object) where T : ConcreteType The question though wasn't too specific, so I didn't get too specific with my answer, yet. I was hoping the user would come back with a more specific question. – Jace Oct 01 '12 at 22:11