3

我有一个接口声明为

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
4

4 回答 4

4

您只需要ConcreteTypeConverterifSomePropertyList不是具体类型,例如

[JsonProperty("someProperty")]
[JsonConverter(typeof(ConcreteTypeConverter<List<T>>))]
IList<T> SomePropertyList{ get; set; }

如果这不是问题,只需将您的属性声明更改为

[JsonProperty("someProperty")]
List<T> SomePropertyList{ get; set; }
于 2013-03-20T11:07:21.353 回答
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无论如何都会返回。

于 2013-03-20T11:31:21.320 回答
0

请在实现接口的类上应用该属性。

[JsonProperty("someProperty")]
[JsonConverter(typeof(ConcreteTypeConverter<List<T>>))]
于 2013-03-20T10:24:12.153 回答
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;
 }

并像这样使用(如果数据将是json中的对象,它将被转换为列表):

public class BaseResponse<TData>
{
    [JsonConverter(typeof(SingleValueToCollectionConverter))]
    public List<TData> Data { get; set; }
}

我希望它可以帮助某人

于 2018-09-19T07:35:39.760 回答