我不确定我说得那么好,但我想做的就是这个。我使用来获得这样的代码:
Select Case name
Case "ThisProperty": ...
Case "ThatProperty": ...
...
End Select
但name
是对象的属性,我想以类型安全的方式执行此操作,因此如果属性更改,我会将其作为编译时错误捕获。所以我想要这种伪代码
Select Case name
Case PropertyName(Of MyType)(Function(x) x.ThisProperty): ...
Case PropertyName(Of MyType)(Function(x) x.ThatProperty): ...
...
End Select
,其中
Function PropertyName(Of T)(propertySpecifier As Expression(Of Func(Of T, Object))) As String
Return {expression magic to get property name as a string}
End Function
我的PropertyName
功能运行正常,但你不能像这样编码Select Case
,即使你可以,我也担心这会非常低效,因为所有的表达操作,无论如何都是一个紧密的循环。 (而且语法也很乏味。)
所以我想知道是否有合理的方法对此进行编码以解决这两个问题。
答案 0 :(得分:1)
正如我在评论中所说,NameOf
运算符将成为即将推出的VB.NET 14中的优势,Visual Studio 2015即将推出。您不必担心效率问题因为它将在编译时进行评估,而不是在运行时使用反射。
与此同时,如果没有创建自己的代码生成预构建操作,最好的选择可能是仅通过反射评估属性名称,并缓存结果。例如,您可以创建一个操作字典,如下所示:
Dim actions As New Dictionary(Of String, Action)()
actions.Add(PropertyName(Of MyType)(Function(x) x.ThisProperty),
Sub() Console.WriteLine("This"))
actions.Add(PropertyName(Of MyType)(Function(x) x.ThatProperty),
Sub() Console.WriteLine("That"))
然后,而不是Select Case
,您可以从字典中拉出所需的操作并执行它:
actions(name).Invoke()
至少那时你只需要在构建字典时获取属性名称一次。在它建成之后在字典中找到它们会非常快。但是,对于简短列表,您可能只想使用SortedList
而不是Dictionary
。
答案 1 :(得分:1)
Steven Doggart所说的是对的。这是一个例子。我已经在我正在进行名称绑定表达式评估的情况下使用了NameOf,它替换了我的所有文字字符串,因此对名称重构具有弹性。
(FWIW,VS2015 CTP6 - (撰写本文时的当前版本) - 稳定且VB和C#都功能齐全)
Sub Main()
Dim name = "x"
Select Case name.ToUpperInvariant
Case NameOf(Grover.x).ToUpperInvariant
Console.WriteLine("Monkey")
Case NameOf(Grover.y).ToUpperInvariant
Console.WriteLine("Giraffe")
Case NameOf(Grover.Cheese).ToUpperInvariant
Console.WriteLine("Ferret")
End Select
Console.ReadKey()
End Sub
Public Class Grover
Public x As Integer
Public y As Integer
Public Cheese As String
End Class
答案 2 :(得分:0)
这是一个正是为了这个目的的例程。它在C#中。 但VB。应该可以接受表达式的静态类的净等价物。也许有一个vb老兄知道如何转换它。
如何处理引用POCO属性的字符串并在更改时获得编译时错误。 你使用一个小的lamda表达式来引用属性,你得到的是名字作为字符串返回。
public static class MyExtUtilites {
public static string PropNameAsExpr<TPoco, TProp>(Expression<Func<TPoco, TProp>> prop) {
var body = prop.Body as System.Linq.Expressions.MemberExpression;
return body == null ? null : body.Member.Name;
}
}
使用此属性作为字符串的属性名称是必需的。 在编译时,必须在MyPoco类中知道属性 propname 。
var propNameAsString = myExtUtilites.PropNameAsExpr((MyPoco p) => myPoco.propname) ;
从随机网站执行c#到vb网络转换。不确定是否可以。
Imports System
Imports System.Linq
Imports System.Linq.Expressions
Public static Class MyExtUtilites
Public static String PropNameAsExpr<TPoco, TProp>(Expression<Func<TPoco, TProp> prop)
{
Dim body As var = prop.Body as System.Linq.Expressions.MemberExpression
Return body = Nothing ? Nothing : body.Member.Name
}
End Class