我有一个c#类,可让您指定泛型类型。我希望能够重用该类来消除所有对象将共享的json包装器的噪音,该属性包含用于保存我需要的数据的value
属性。
如果可重用类的属性为value
,这使我迈出了第一步。但是我在将反序列化为提供的泛型类型时遇到了麻烦,因为当我强制转换时,它总是返回null
。我知道这是因为反序列化后value
的实际类型可能是JObject
或类似的类型,我完全忘记了该类型。您可以在演示应用程序中看到它确实可以捕获所有数据,但是我不能仅仅将其转换为通用类型,因为它实际上还不是该类型。
var get1 = JsonConvert.DeserializeObject<BaseResponse<NameObj>>("{ value: {...} }");
var name1 = get1.Get();//name1 is null
var getList1 = JsonConvert.DeserializeObject<BaseResponse<NameObj>>("{ value: [{...}] }");
var nameList = getList1.List();//nameList is null
public class BaseResponse<T> where T : BaseObj
{
public object value;
public T Get()
{
return value as T;
}
public List<T> List()
{
return value as List<T>;
}
}
public class NameObj : BaseObj
{
public string Name { get; set; }
}
我将拥有不止一种BaseObj类。
所以,我想知道哪种更好:
value
,然后反序列化BaseReponse<T>
进行反序列化以更好地了解value
属性内部的泛型我想解决方案1现在就可以了,因为所有的json都遵循该模式,但是我希望进行一次纯粹的反序列化,而不必进行字符串处理。
在此处回购:https://github.com/nateous/JSONDeserializeBaseWithGeneric
答案 0 :(得分:1)
您的问题是,在键入$ vars="-n"
$ printf '%s\n' "$vars"
-n
的同时,底层数据成员BaseResponse<T>
的类型也没有,因此Json.NET不知道如何反序列化它。实际上,它要做的是将反序列化为某种类型,该类型足以捕获要反序列化的JSON,通常是某些JToken
层次结构。
由于您不需要这样做,因此应输入属性,例如像这样:
public object value
由于值并不总是从public abstract class BaseResponseBase
{
// Allows for non-generic access to the BaseResponse value if needed
// Use a method rather than a property to prevent accidental serialization.
public abstract object GetBaseValue();
}
public class BaseResponse<T> : BaseResponseBase
{
public override object GetBaseValue() { return Value; }
public T Value { get; set; }
}
继承(特别是当它是列表而不是对象时),因此通用约束不再适用。 BaseObj
提供对反序列化值的非通用访问。如果永远不需要这种访问,则可以省略基类。
然后要反序列化,请执行以下操作:
BaseResponseBase
偶然地,您始终可以使用JsonConvert.DeserializeAnonymousType
来剥离外部容器对象:
var name = JsonConvert.DeserializeObject<BaseResponse<NameObj>>("{ value: {...} }").Value;
var nameList = JsonConvert.DeserializeObject<BaseResponse<List<NameObj>>>("{ value: [{...}] }").Value;
这比使用字符串操作反序列化JSON更为严格。
答案 1 :(得分:1)
要解决此问题:
var get1 = JsonConvert.DeserializeObject<BaseResponse<NameObj>>("{ value: {...} }");
var name1 = get1.Get();//name1 is null
将BaseResponse类中的值类型从object更改为T。
public class BaseResponse<T> where T : BaseObj
{
public T value; //from object to T
public T Get()
{
return value as T;
}
public List<T> List()
{
return value as List<T>;
}
}
现在,此:
var getList1 = JsonConvert.DeserializeObject<BaseResponse<NameObj>>("{ value: [{...}] }");
var nameList = getList1.List();//nameList is null
反序列化ListBaseJSON返回BaseObj数组,但是BaseResponse类具有BaseObj约束。您可能必须删除约束。
因此您的BaseResponse类变为:
public class BaseResponse<T>
{
public T value;
public T Get()
{
return value;
}
}
因此,现在您可以:
var get1 = JsonConvert.DeserializeObject<BaseResponse<NameObj>>("{ value: {...} }");
var name1 = get1.Get();//name1 is null
var getList1 = JsonConvert.DeserializeObject<BaseResponse<NameObj>>("{ value: [{...}] }");
var nameList = getList1.List();//nameList is null