0

I have a class called Foo, as shown in the example below. The Content property of this class is a generic list type. I want to check if the Content property has one or more items. But I am getting an error as "an attribute argument cannot use type parameters". I'm waiting for your help on this. Thanks in advance..

[DataContract]
public class Foo<T> where T : class
{
    [JsonConverter(typeof(SingleOrMany<T>))]
    public List<T> Content { get; set; }
}

public class SingleOrMany<T> : JsonConverter
{
    public override bool CanConvert(System.Type objectType)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, System.Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

My question is different from the example below. Here T is used in a generic list.

[JsonConverter(typeof(ConcreteTypeConverter<List<T>>))]
Abdullah Elen
  • 534
  • 4
  • 13
  • 1
    You can't pass generic parameter to attribute. – SᴇM Jan 29 '19 at 08:22
  • Attribute arguments must be compile-time constant(Simple types, string, enums etc) – styx Jan 29 '19 at 08:25
  • Possible duplicate of [Pass C# generic type as a parameter](https://stackoverflow.com/questions/15520317/pass-c-sharp-generic-type-as-a-parameter) – SᴇM Jan 29 '19 at 08:27
  • As @SeM said you can't use a generic parameter in an attribute; see [Why does C# forbid generic attribute types?](https://stackoverflow.com/q/294216). But is `SingleOrMany` designed to handle the case when the corresponding JSON property could be a single item or an array of items? If so, try using one of the "universal" non-generic converters from [How to handle both a single item and an array for the same property using JSON.net](https://stackoverflow.com/q/18994685/3744182), for instance `SingleOrArrayListConverter` from [here](https://stackoverflow.com/a/53771970/3744182). – dbc Jan 29 '19 at 08:42
  • 1
    I'm pretty sure `System.Type objectType` in `ReadJson` would represent `List`, so couldn't you exact T from there, rather than passing it via a generic parameter? –  Jan 29 '19 at 09:08

1 Answers1

0

Your class doesn't even use T. Just remove it. You can obtain type information from the arguments that are passed in (e.g. objectType).

Once T is removed, you can pass typeof(SingleOrMany) to the attribute without issue.

[DataContract]
public class Foo<T> where T : class
{
    [JsonConverter(typeof(SingleOrMany))]
    public List<T> Content { get; set; }
}

public class SingleOrMany : JsonConverter
{
    public override bool CanConvert(System.Type objectType)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, System.Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
John Wu
  • 50,556
  • 8
  • 44
  • 80