能否通过反射获取点标记访问的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
相关产品推荐
相关产品推荐

