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

必要なのは、具体的なタイプではないConcreteTypeConverter場合のみです。SomePropertyList

[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

を削除しましたTConcreteReadJsonはオブジェクトを返すため、ジェネリックスの力は単純に薄れていきます。

2番、

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が1つ必要でした。そして、振り返りは私を助けました:

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 に答える