C# 从C类中获取JSON PropertyName,比如JSON属性的“nameof(Class.prop)”?

C# 从C类中获取JSON PropertyName,比如JSON属性的“nameof(Class.prop)”?,c#,json,reflection,C#,Json,Reflection,如何获取以下类和属性的JSON PropertyName?类似于JSON属性的等效名称 比如说 var jsonName=GetJSONPropertyNameSampleClass.SampleClassID//应该返回jsoniD 一个好问题是,如何以类型安全的方式传递属性。属性不是.NET中的一级对象 其中一种方法是: using System.Linq.Expressions; // ... static string GetJsonPropertyName<TC, TP>

如何获取以下类和属性的JSON PropertyName?类似于JSON属性的等效名称

比如说

var jsonName=GetJSONPropertyNameSampleClass.SampleClassID//应该返回jsoniD


一个好问题是,如何以类型安全的方式传递属性。属性不是.NET中的一级对象

其中一种方法是:

using System.Linq.Expressions;

// ...

static string GetJsonPropertyName<TC, TP>(Expression<Func<TC, TP>> expr)
{
    if (expr.Body is MemberExpression body)
        return body.Member.GetCustomAttribute<JsonPropertyAttribute>()?.PropertyName;
    else
        throw new ArgumentException("expect field access lambda");
}
您需要像这样调用函数:

var jsonName = GetJsonPropertyName<SampleClass, string>(x => x.SampleClassID);
static string GetJsonPropertyName<TC>(Expression<Func<TC, object>> expr)
{
    // in case the property type is a value type, the expression contains
    // an outer Convert, so we need to remove it
    var body = (expr.Body is UnaryExpression unary) ? unary.Operand : expr.Body;

    if (body is System.Linq.Expressions.MemberExpression memberEx)
        return memberEx.Member.GetCustomAttribute<JsonPropertyAttribute>()?.PropertyName;
    else
        throw new ArgumentException("expect field access lambda");
}

var jsonName = GetJsonPropertyName<SampleClass>(x => x.SampleClassID);
是的,感觉不太自然。对不起

由于@elgonzo,代码可以简化如下:

var jsonName = GetJsonPropertyName<SampleClass, string>(x => x.SampleClassID);
static string GetJsonPropertyName<TC>(Expression<Func<TC, object>> expr)
{
    // in case the property type is a value type, the expression contains
    // an outer Convert, so we need to remove it
    var body = (expr.Body is UnaryExpression unary) ? unary.Operand : expr.Body;

    if (body is System.Linq.Expressions.MemberExpression memberEx)
        return memberEx.Member.GetCustomAttribute<JsonPropertyAttribute>()?.PropertyName;
    else
        throw new ArgumentException("expect field access lambda");
}

var jsonName = GetJsonPropertyName<SampleClass>(x => x.SampleClassID);

一个好问题是,如何以类型安全的方式传递属性。属性不是.NET中的一级对象

其中一种方法是:

using System.Linq.Expressions;

// ...

static string GetJsonPropertyName<TC, TP>(Expression<Func<TC, TP>> expr)
{
    if (expr.Body is MemberExpression body)
        return body.Member.GetCustomAttribute<JsonPropertyAttribute>()?.PropertyName;
    else
        throw new ArgumentException("expect field access lambda");
}
您需要像这样调用函数:

var jsonName = GetJsonPropertyName<SampleClass, string>(x => x.SampleClassID);
static string GetJsonPropertyName<TC>(Expression<Func<TC, object>> expr)
{
    // in case the property type is a value type, the expression contains
    // an outer Convert, so we need to remove it
    var body = (expr.Body is UnaryExpression unary) ? unary.Operand : expr.Body;

    if (body is System.Linq.Expressions.MemberExpression memberEx)
        return memberEx.Member.GetCustomAttribute<JsonPropertyAttribute>()?.PropertyName;
    else
        throw new ArgumentException("expect field access lambda");
}

var jsonName = GetJsonPropertyName<SampleClass>(x => x.SampleClassID);
是的,感觉不太自然。对不起

由于@elgonzo,代码可以简化如下:

var jsonName = GetJsonPropertyName<SampleClass, string>(x => x.SampleClassID);
static string GetJsonPropertyName<TC>(Expression<Func<TC, object>> expr)
{
    // in case the property type is a value type, the expression contains
    // an outer Convert, so we need to remove it
    var body = (expr.Body is UnaryExpression unary) ? unary.Operand : expr.Body;

    if (body is System.Linq.Expressions.MemberExpression memberEx)
        return memberEx.Member.GetCustomAttribute<JsonPropertyAttribute>()?.PropertyName;
    else
        throw new ArgumentException("expect field access lambda");
}

var jsonName = GetJsonPropertyName<SampleClass>(x => x.SampleClassID);
基于@Vlad解决方案的工作值类型表达式支持 一元表达式模式从

基于@Vlad解决方案的工作值类型表达式支持 一元表达式模式从


不确定Newtonsoft.Json我假设您正在使用的库是否具有用于此目的的实用程序函数。但如果没有,您可以通过反射检查类型及其成员,查看它们是否具有特定属性,以及这些属性的值是什么:@elgonzo描述了如何执行此操作。要意识到,这与nameof不同。关键字nameof在编译时工作并且没有运行时开销,您的GetJsonPropertyName函数将在运行时运行,调用反射来执行workDuplicate或相关:和和。不确定Newtonsoft.Json我假设您使用的库是否具有用于此目的的实用函数。但如果没有,您可以通过反射检查类型及其成员,查看它们是否具有特定属性,以及这些属性的值是什么:@elgonzo描述了如何执行此操作。要意识到,这与nameof不同。nameof关键字在编译时工作,没有运行时开销,GetJsonPropertyName函数将在运行时运行,调用反射来执行workDuplicate或相关的:and。我想方法的签名可以稍微简化,只需要提供属性作为泛型类型参数的类型,方法是用object:static string GetJsonPropertyNameExpression{…}替换TP。然后调用该方法不需要知道属性类型:GetJsonPropertyNamex=>x.SampleClassID;不多,但像这样的小事情有时可以走很长的路-@埃尔贡佐:真的!我错误地担心x=>x.SampleClassID不能转换为Func。非常感谢。不确定它是否是.NET标准、我的属性是值类型还是其他类型,但我的expr.Body不是MemberExpression,它是操作数属性中带有MemberExpression的一元表达式。根据您的回答,我发布了另一个带有.NET标准解决方案的回复。我想该方法的签名可以稍微简化,只需要提供属性作为泛型类型参数的类型,方法是将TP替换为object:static string GetJsonPropertyNameExpression{…}。然后调用该方法不需要知道属性类型:GetJsonPropertyNamex=>x.SampleClassID;不多,但像这样的小事情有时可以走很长的路-@埃尔贡佐:真的!我错误地担心x=>x.SampleClassID不能转换为Func。非常感谢。不确定它是否是.NET标准、我的属性是值类型还是其他类型,但我的expr.Body不是MemberExpression,它是操作数属性中带有MemberExpression的一元表达式。根据您的回答,我发布了另一个带有.NET标准解决方案的回复。哦,我明白了:问题是,对于值类型的属性,我们需要将属性值额外转换为对象。我的答案中的第一个版本的代码在这种情况下也能很好地工作,但需要一个额外的泛型参数。@Vlad,我对您的代码进行改进的应用程序,结果证明它是不完整/错误的建议。我检查了几年前我自己编写的一些代码,这些代码简化了dependencProperties的创建,基于计算lambda表达式来获得属性名,瞧,我实际上也检查并处理了那里的UnaryExpressions。我完全忘记了。哦…@elgonzo:事实上,我仍然认为你的建议是一种改进:额外检查的成本可以忽略不计,删除一个额外的参数是一件好事!非常感谢。哦,我明白了:问题是,在值类型属性的情况下,我们需要将属性值额外转换为对象。我的答案中的第一个版本的代码在这种情况下也能很好地工作,但是r
需要一个额外的泛型参数。@Vlad,我的建议,用于改进您的代码,但事实证明这是不完整/错误的建议。我检查了几年前我自己编写的一些代码,这些代码简化了dependencProperties的创建,基于计算lambda表达式来获得属性名,瞧,我实际上也检查并处理了那里的UnaryExpressions。我完全忘记了。哦…@elgonzo:事实上,我仍然认为你的建议是一种改进:额外检查的成本可以忽略不计,删除一个额外的参数是一件好事!非常感谢。