You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否通过反射获取点标记访问的resx字符串的资源键名?

实现方案

完全可以通过表达式树实现强类型获取资源键,不需要手写字符串字面量,资源不存在/拼写错误时VS会直接报编译错误,符合你的需求。

第一步:实现强类型获取资源属性名的辅助方法

先写一个通用的辅助函数,接收强类型资源的属性访问表达式,直接返回对应的属性名(也就是资源键):

Imports System.Linq.Expressions
Imports System.Reflection
Imports System.Resources
Imports System.Threading

' 辅助方法:从强类型资源访问表达式中获取资源键名
Public Function GetResourceKey(Of T)(resourceAccessor As Expression(Of Func(Of T))) As String
    Dim memberExpr As MemberExpression = TryCast(resourceAccessor.Body, MemberExpression)
    If memberExpr Is Nothing OrElse Not TypeOf memberExpr.Member Is PropertyInfo Then
        Throw New ArgumentException("参数必须是强类型资源的属性访问表达式,例如 Function() MyStrings.This_is_a_test_string")
    End If
    Return memberExpr.Member.Name
End Function

第二步:改造原有错误信息获取方法(可选,也可以直接用上面的方法传参)

你也可以直接把方法改成直接接收表达式,连资源基名也不用手动传,进一步简化调用,同时还优化了原有切换全局线程语言的逻辑,避免影响其他业务的语言设置:

' 改造后的多语言错误信息获取方法,支持强类型调用
Public Function GetCustomErrorMsgStrings(Of T)(resourceAccessor As Expression(Of Func(Of T))) As String
    ' 从表达式获取属性信息和所属资源类型
    Dim memberExpr As MemberExpression = TryCast(resourceAccessor.Body, MemberExpression)
    Dim resourceProperty As PropertyInfo = TryCast(memberExpr.Member, PropertyInfo)
    Dim resourceType As Type = resourceProperty.DeclaringType
    
    ' 直接用强类型资源类自带的ResourceManager,不用自己实例化
    Dim rm As ResourceManager = CType(resourceType.GetProperty("ResourceManager", BindingFlags.Public Or BindingFlags.Static).GetValue(Nothing), ResourceManager)
    
    ' 直接指定Culture参数获取对应语言资源,不需要切换全局线程语言,无副作用
    Dim strLocal As String = rm.GetString(resourceProperty.Name, Thread.CurrentThread.CurrentUICulture)
    Dim strEnglish As String = rm.GetString(resourceProperty.Name, Globalization.CultureInfo.GetCultureInfo("en"))
    
    Return $"Local Text: {strLocal}||||{vbNewLine}English: {strEnglish}"
End Function

调用方式(完全强类型,VS实时校验)

' 直接写强类型访问,写错资源名直接编译报错
strCustomErrorMsg = GetCustomErrorMsgStrings(Function() MyStrings.This_is_a_test_string)

原有方法兼容调用方式

如果你不想改造原有方法,也可以直接用第一个辅助方法获取键名后传给原来的函数:

Dim resourceKey = GetResourceKey(Function() MyStrings.This_is_a_test_string)
strCustomErrorMsg = GetCustomErrorMsgStrings(MyStrings.ResourceManager.BaseName, resourceKey)

内容的提问来源于stack exchange,提问作者MatthewNYC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 07:54:01