2013-03-20 7 views
3

я интерфейс объявлен какPass C# универсальный тип в качестве параметра

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 и возвращает конкретную реализацию T, которая необходима для десериализации JSON. Сценарий здесь состоит в том, что T может иметь около 20 различных типов. Но я хотел бы избежать наличия 20 таких интерфейсов - вот почему я выбрал общий интерфейс.

Usage будет что-то вроде

ISomething<SomeType> variable = new Something<SomeType>(); 
var list = variable.SomePropertyList; 

где SomeType фактическая реализация Т. Есть ли способ, чтобы использовать дженерики в такой ситуации?

Мои 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 
+1

Итак, ваш вопрос носит общий характер как атрибут? Можете ли вы вставить свой код ConcreteTypeConverter (просто класс def). –

+2

Также будет полезен точный вывод ошибок. –

+0

Отредактировал вопрос, добавив дополнительную информацию. Да, в основном y вопрос возобновляется до «Могу ли я отправить общий тип T как атрибут?» – drl

ответ

4

Вам нужно только ConcreteTypeConverter если SomePropertyList не конкретный тип, например,

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

Если это не проблема, просто изменить свое объявление свойства в

[JsonProperty("someProperty")] 
List<T> SomePropertyList{ get; set; } 
0

Пожалуйста применить атрибут класса, реализующего интерфейс.

[JsonProperty("someProperty")] 
[JsonConverter(typeof(ConcreteTypeConverter<List<T>>))] 
1

Цитирование:

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

Я получаю сообщение об ошибке на ConcreteTypeConverter

Sinc е общие параметры не могут появляться в объявлениях атрибутов, есть совет для вас от меня:

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.

Смежные вопросы