为什么 JsonConverter 属性没有从接口继承?
Why is JsonConverter attribute not inherited from interface?
中有以下代码:
interface ITyped<TypeEnum> where TypeEnum : Enum, struct
{
[JsonConverter(typeof(JsonStringEnumConverter))]
public TypeEnum Type { get; }
}
class Foo : ITyped<FooType>
{
public Foo(FooType type) { Type = type; }
public FooType Type { get; init; }
}
enum FooType { type1, type2 }
如果我用 System.Text.Json.JsonSerializer
序列化 Foo
实例,我会得到 Type
属性 的 int
- 尽管我指定了 JsonStringEnumConverter
对于 Type
属性 在 interface
.
var foo = new Foo(FooType.type1);
var json = JsonSerializer.Serialize(foo);
// contains {"Type":0} but I want {"Type":"type1"}
如果我将 [JsonConverter(typeof(JsonStringEnumConverter))]
附加到 Foo
的 Type
属性,它确实有效。
但是为什么附加到interface
的Type
属性就不行了?
docs 说 JsonConverterAttribute
可以放在 System.AttributeTargets.Property
上,因为它派生自 Attribute
,所以也是 Inherited=true
。
关键部分是 classes 实现接口,它们不继承它们。
我看到以下选项:
- 使用基数class
- “全局”使用 JsonStringEnumConverter 而不是装饰单个成员:
var options = new JsonSerializerOptions();
options.Converters.Add(new JsonStringEnumConverter());
JsonSerializer.Serialize(foo);
中有以下代码:
interface ITyped<TypeEnum> where TypeEnum : Enum, struct
{
[JsonConverter(typeof(JsonStringEnumConverter))]
public TypeEnum Type { get; }
}
class Foo : ITyped<FooType>
{
public Foo(FooType type) { Type = type; }
public FooType Type { get; init; }
}
enum FooType { type1, type2 }
如果我用 System.Text.Json.JsonSerializer
序列化 Foo
实例,我会得到 Type
属性 的 int
- 尽管我指定了 JsonStringEnumConverter
对于 Type
属性 在 interface
.
var foo = new Foo(FooType.type1);
var json = JsonSerializer.Serialize(foo);
// contains {"Type":0} but I want {"Type":"type1"}
如果我将 [JsonConverter(typeof(JsonStringEnumConverter))]
附加到 Foo
的 Type
属性,它确实有效。
但是为什么附加到interface
的Type
属性就不行了?
docs 说 JsonConverterAttribute
可以放在 System.AttributeTargets.Property
上,因为它派生自 Attribute
,所以也是 Inherited=true
。
关键部分是 classes 实现接口,它们不继承它们。
我看到以下选项:
- 使用基数class
- “全局”使用 JsonStringEnumConverter 而不是装饰单个成员:
var options = new JsonSerializerOptions(); options.Converters.Add(new JsonStringEnumConverter()); JsonSerializer.Serialize(foo);