Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 强制转换泛型参数_C#_Generics - Fatal编程技术网

C# 强制转换泛型参数

C# 强制转换泛型参数,c#,generics,C#,Generics,我从一个方法中得到一个对象。对象的类型为object,由于向后兼容,我无法更改此类型。如果它属于某种类型(Responsebellow),那么我需要访问Payload属性,它属于T类型,这样我就可以将它序列化为另一个对象的一部分并发送出去。问题是,由于我不知道t的类型,因此无法将对象强制转换为Response以访问有效负载,即使我不关心它的类型 这是我的泛型对象: public class Response { public int Status { get; set; } publ

我从一个方法中得到一个对象。对象的类型为object,由于向后兼容,我无法更改此类型。如果它属于某种类型(
Response
bellow),那么我需要访问
Payload
属性,它属于
T
类型,这样我就可以将它序列化为另一个对象的一部分并发送出去。问题是,由于我不知道
t
的类型,因此无法将对象强制转换为
Response
以访问
有效负载
,即使我不关心它的类型

这是我的泛型对象:

public class Response
{
   public int Status { get; set; }
   public string Message { get; set; }
}

public class Response<T> : Response
{
   public T Payload { get; set; }
}
公共类响应
{
公共int状态{get;set;}
公共字符串消息{get;set;}
}
公共课回应:回应
{
公共T有效载荷{get;set;}
}
以下是我想做的:

// Will sometimes be of type Response<T>
object data = LegacyCode();
if (data.GetType().IsGenericType && data.GetType().GetGenericTypeDefinition() == typeof(Response<>)) {
   var payload = ((Response<object>)data).Payload; // Unable to cast object of type...
}
//有时会是Response类型
对象数据=LegacyCode();
if(data.GetType().IsGenericType&&data.GetType().GetGenericTypeDefinition()==typeof(响应)){
var payload=((响应)数据)。payload;//无法强制转换类型为的对象。。。
}
但我能找到的唯一方法是使用动力学

// Will sometimes be of type Response<T>
object data = LegacyCode();
if (data.GetType().IsGenericType && data.GetType().GetGenericTypeDefinition() == typeof(Response<>)) {
   var payload = ((dynamice)data).Payload;     
}
//有时会是Response类型
对象数据=LegacyCode();
if(data.GetType().IsGenericType&&data.GetType().GetGenericTypeDefinition()==typeof(响应)){
var有效载荷=((动态)数据);
}
不要问为什么事情会这样(我自己也很奇怪)。我必须做代码练习来保持这个系统的向后兼容性我只想在编译时检查属性的名称。

这是一把小提琴:

更新:

我需要能够序列化和反序列化这个对象。最初
响应
具有类型为
对象
的属性
有效负载
。这会在反序列化
响应
时导致序列化问题,因为
有效负载
属性的类型为
Newtonsoft.Json.Linq.JObject
,无法转换为
T
。以下是一个例子:

问题是我走错了方向,如果我将
T
转换为
object
,而不是尝试将
object
转换为
T
,反序列化就会起作用。当我将该值存储为其特定类型
T
时,序列化程序知道将字符串反序列化为什么。 下面是一个使用Jon回答的示例:


下面是一个使用Matias使用协方差的解决方案的类似示例:

要在编译时检查属性的名称,可以保留动态键入,但需要运行时“迷你编译器”来完成这项艰巨的工作:

object data = LegacyCode();
object payload = GetPayload(data);
// Use payload

...

private static object GetPayload<T>(Response<T> response)
{
    return response.Payload;
}

public static object GetPayload(object data)
{
    // Fallback method. You could return null here and use
    // that to indicate in the calling code that it wasn't a
    // Response<T>...
}

我相信你需要使用

设计接口
i响应

公共接口i响应
{
公共T有效负载{get;}
}
并在
响应
上实现它。现在您可以将其转换为
i响应

Response x=新响应();
i响应y=x;//隐式铸造

不清楚您想做什么。。。
数据
是否意味着是
类型
而不是该类型的实例?这就是您调用的结果,但是您试图将其转换为
Response
…并且您是否可以更改
Response
,例如,使用非泛型抽象基类型?抱歉。数据是一个类型的实例。它有时是响应类型。我真的无法改变这是“有时”的事实。但我需要特别处理它。我以前使用非泛型基类,但在客户端上出现序列化问题,无法将非泛型有效负载属性解除绑定到其泛型类型。谢谢!我的序列化问题是我走错了方向。我将有效负载保存在类型为object的Response上的属性中,并从Response引用它,而不是将有效负载保存在类型为T的属性中,并使用属性将其强制转换为对象。我将在我的问题中添加代码示例的链接来说明这一点。我不得不使用这个解决方案,因为枚举不支持协方差,就像其他解决方案所要求的那样。谢谢!我希望我能把你和乔恩的答案都标记为答案。我将使用您的解决方案添加一个示例。@bygrace没问题。这里的答案提供了解决同一问题的更多方法。它将对未来的访问者(甚至是你)有用
public class Response
{
   public int Status { get; set; }
   public string Message { get; set; }
}

public interface IPayloadHolder
{
    public object Payload { get; }
}

public class Response<T> : Response, IPayloadHolder
{
   public T Payload { get; set; }

   // By using explicit interface implementation, this
   // doesn't get in the way for normal usage.
   IPayloadHolder.Payload { get { return Payload; } }
}
var payloadHolder = data as IPayloadHolder;
if (payloadHolder != null)
{
    var payload = payloadHolder.Payload;
}
public interface IResponse<out T>
{
   public T Payload { get; }
}
Response<string> x = new Response<string>();
IResponse<object> y = x; // implicit cast