我有一个声明为
的接口public interface ISomething<T> where T : class
在界面的某个地方我有一个声明为
的成员[JsonProperty("someProperty")]
[JsonConverter(typeof(ConcreteTypeConverter<List<T>>))]
List<T> SomePropertyList{ get; set; }
我在ConcreteTypeConverter<List<T>>
上收到错误,说它不能使用类型(T)作为参数。我的ConcreteTypeConverter类采用类型T并返回JSON反序列化所需的T的具体实现。这里的场景是T可以有大约20种不同的类型。但我想避免使用20个这样的接口 - 这就是我选择的原因通用界面。
用法类似于
ISomething<SomeType> variable = new Something<SomeType>();
var list = variable.SomePropertyList;
其中SomeType是T的实际实现。在这种情况下有没有办法使用泛型?
我的ConcreteConverterClass派生自JsonConverter(使用Newtonsoft.Json):
public class ConcreteTypeConverter<TConcrete> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return serializer.Deserialize<TConcrete>(reader);
}
}
我的确切错误是:
Attribute Argument cannot use type parameters
答案 0 :(得分:4)
如果ConcreteTypeConverter
不是具体类型,则只需要SomePropertyList
,例如。
[JsonProperty("someProperty")]
[JsonConverter(typeof(ConcreteTypeConverter<List<T>>))]
IList<T> SomePropertyList{ get; set; }
如果这不是问题,只需将您的财产声明更改为
即可[JsonProperty("someProperty")]
List<T> SomePropertyList{ get; set; }
答案 1 :(得分:1)
引用:
[JsonConverter(typeof(ConcreteTypeConverter<List<T>>))]
List<T> SomePropertyList{ get; set; }
我在ConcreteTypeConverter
上收到错误
由于通用参数不能出现在属性声明中,因此我可以为您提供建议:
public class ConcreteTypeConverter : JsonConverter
删除了TConcrete
。由于ReadJson
返回一个对象,因此泛型的功能会逐渐淡出。
其次,
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return serializer.Deserialize<object>(reader);
}
用对象替换TConcrete
。如果这还不足以使您的代码工作,请尝试解决它。无论如何,您的方法返回object
。
答案 2 :(得分:0)
请在实现界面的类上应用该属性。
[JsonProperty("someProperty")]
[JsonConverter(typeof(ConcreteTypeConverter<List<T>>))]
答案 3 :(得分:0)
如前所述,泛型参数无法出现在属性声明中,我遇到了同样的问题,以前的建议也不适合我,我需要一个SingleValueToCollectionConverter,它可以像泛型一样工作。反思帮助了我:
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
foreach (var prop in objectType.GetProperties())
{
var type = prop.PropertyType;
if (!type.IsClass)
continue;
var destination = Activator.CreateInstance(objectType);
var result = reader.TokenType == JsonToken.StartArray
? serializer.Deserialize(reader, objectType)
: new List<object> { serializer.Deserialize(reader, type) };
return Mapper.Map(result, destination, result.GetType(), destination.GetType());
}
return null;
}
并像这样使用(如果Data将是json中的Object,它将被转换为列表):
public class BaseResponse<TData>
{
[JsonConverter(typeof(SingleValueToCollectionConverter))]
public List<TData> Data { get; set; }
}
我希望它可以帮助某人