我有一个对象作为ISomething传递给我。 我需要序列化对象,但我的serilizer需要一个具体类型的类型参数,即:
string xml = Utilities.Serialize<ConcreteType>(myObject);
基本上我想和这个人做同样的事情:Creating a generic object based on a Type variable
但是我不想创建一个对象的新实例,我想将结果类型用作我的泛型类的参数。
所以我的问题简单来说就是如何创建一个代表某些对象的具体类型的变量,我可以使用这样的泛型类:
string xml = Utilities.Serialize<ConcreteType>(myObject);
其中ConcreteType是我需要创建的。
答案 0 :(得分:2)
所以,让我们说你有类似的东西:
public static class Util
{
public static T Foo<T>(object obj)
{
// Do actual stuff here
return default(T);
}
}
通常,编译器会连接此方法的任何用法,根据您传递的内容交换适当的泛型变体。如果你有一个包含类型的变量,我们就不再可以依赖编译器了 - 但我们可以让班级给我们提供我们想要的变体:
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});
}
答案 1 :(得分:0)
如果您确实需要获取实际对象的类型,则可以使用GetType()。问题是,你必须使用反射来调用所有函数,因为据我所知,没有简单的方法用类型变量调用它们。
答案 2 :(得分:0)
你不能保证所有ISomething
都是ConcreteType
,但是你可以投射它们并传递那些有效的。{/ p>
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;
}
}
答案 3 :(得分:-2)
可能是另一种形式的泛型方法的情况。如果您拥有Utilities.Serialize(...)并且可以生成新的重载,请查看:
http://msdn.microsoft.com/en-US/library/twcad0zb(v=VS.80).aspx
例如:
string Utilities.Serialize<T>(T object)
where T : ConcreteType
经过进一步的反思(双关语),以下是你想要的吗?