3

我有一个作为 ISomething 传递给我的对象。我需要序列化对象但是我的序列化器需要一个具体类型的类型参数,即:

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

基本上我想和这个人做同样的事情:Creating a generic object based on a Type variable

但是我不想创建一个对象的新实例,我想将结果类型用作我的泛型类的参数。

因此,简而言之,我的问题是如何创建一些变量来表示可以与这样的泛型类一起使用的某个对象的具体类型:

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

其中 ConcreteType 是我需要创建的。

4

4 回答 4

3

所以假设你有类似的东西:

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

通常,编译器会连接此方法的任何用法,根据您传递的内容交换适当的通用变体。如果你有一个包含Type的变量,我们就不能再依赖编译器了——但是我们可以要求类给我们想要的变体:

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});
}
于 2012-10-02T02:45:53.407 回答
0

如果您绝对需要获取实际对象的类型,您可以使用 GetType()。问题是,您将不得不使用反射来调用所有函数,因为据我所知,没有简单的方法可以使用具有类型的变量来调用它们。

于 2012-10-01T22:05:42.597 回答
0

您不能保证所有ISomething's 都是ConcreteType's,但您可以将它们转换并传递那些有效的。

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.
    }
}

这是一个更通用的版本,它适用于任何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;
    }
}
于 2012-10-01T22:16:07.550 回答
-2

可能是另一种形式的通用方法的情况。如果您拥有 Utilities.Serialize(...) 并且可以生成新的重载,请查看:

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

例如:

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

经过进一步思考(双关语),您正在寻找以下内容吗?

使用动态类型调用泛型方法

于 2012-10-01T22:03:16.280 回答