如何在 .NET 2.0 中编写一个简单的类似表达式的类?

Posted

技术标签:

【中文标题】如何在 .NET 2.0 中编写一个简单的类似表达式的类?【英文标题】:How to write a simple Expression-like class in .NET 2.0? 【发布时间】:2010-07-07 18:25:01 【问题描述】:

我目前正在使用 .NET 2.0 Visual Basic。当前项目是一个 Active Directory Wrapper 类库,其中我有一个 Searcher(Of T) 泛型类,我希望使用它来搜索底层目录中的对象。

在这个Searcher(Of T) 类中,我有以下方法:

Private Function GetResults() As CustomSet(Of T)
Public Function ToList() As CustomSet(Of T)
Public Function Find(ByVal ParamArray filter() As Object) As CustomSet(Of T)
// And some other functions here...

我最感兴趣的是 Find() 方法,我可以将属性和值传递给该方法,并希望从这个 filter() ParamArray 参数解析我的 LDAP 查询。其实,我能想到的只有这个:

Public Sub SomeSub()
    Dim groupSearcher As Searcher(Of Group) = New Searcher(Of Group)()
    Dim groupsSet as CustomSet(Of Group) = groupSearcher.Find("Name=someName", "Description=someDescription")

    // Working with the result here...
End Sub

但我希望能够为我的用户提供的是:

Public Sub SomeSub()
    Dim groupSearcher As Searcher(Of Group) = New Searcher(Of Group)()
    Dim groupsSet As CustomSet(Of Groupe) = groupSearcher.Find(Name = "someName", Guid = someGuid, Description = "someDescription")

    // And work with the result here...
End Sub

简而言之,我想为我的用户提供某种Expression 功能,除非工作量太大,因为这个项目不是最重要的,而且我没有两年的时间来开发它。我认为我应该做的更好的事情是编写类似CustomExpression 的东西,可以将参数传递给某些函数或子函数。

感谢任何可能使我实现目标的建议!

【问题讨论】:

【参考方案1】:

有趣的问题。这是一个依赖于语言的功能,所以如果没有 IDE/编译器的一些巧妙技巧,我不会看到这种情况发生。

但是,您可以在 Find 方法上有可选的重载(vb.net 对此很有用),然后手动创建搜索字符串以获得结果。

最后,您可以使用 lambda 函数,但仅限于 .net 3.5 及更高版本。即便如此,它仍需要您的搜索者公开一组初步数据,以便您可以恢复表达式树并构建查找字符串。

更新

我一直在玩反射,看看我是否可以检索传递的参数,并根据它们是否存在动态构建一个字符串。这似乎是不可能的,因为编译后的代码没有引用名称。

刚刚使用的这段代码是:

'-- Get all the "parameters"
Dim m As MethodInfo = GetType(Finder).GetMethod("Find")
Dim params() As ParameterInfo = m.GetParameters()
'-- We now have a reference to the parameter names, like Name and Description

嗯。 http://channel9.msdn.com/forums/TechOff/259443-Using-SystemReflection-to-obtain-parameter-values-dynamically/

令人讨厌的是,恢复发送的值并不(容易),因此我们必须坚持以非动态方式构建字符串。

一个简单的可选方法如下所示:

Public Sub Find( _
               Optional ByVal Name As String = "", _
               Optional ByVal Description As String = "")

    Dim query As String = String.Empty
    If Not String.IsNullOrEmpty(Name) Then
        query &= "Name=" & Name
        '-- ..... more go here with your string seperater.
    End If
End Sub

【讨论】:

+1 用于Find 方法的可选重载。此外,我已经关注了 .NET 3.5 中的 Expression 类及其派生类型,我认为有一种方法可以以某种方式编写这些类,它可以解析某种表达式,然后执行适当的查询。但这似乎是为了它的价值而付出的太多努力。尽管如此,我的意思是在业余时间写这样一门课,如果只是为了了解引擎盖下的内容,也可能是为了提高我的技能。我基本上是一个 C# 程序员,所以可以举一个可选重载的例子吗?谢谢 我在我之前的回答中添加了一些内容,也许一些编译器大师可以帮助我们解决我还不能做的事情......

以上是关于如何在 .NET 2.0 中编写一个简单的类似表达式的类?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 .NET 2.0 安全地托管插件

简单的多行正则表达式在 .NET 中失败,但在 ECMAScript 中成功 - 为啥?

如何在 AWS CDK 2.0 中编写稀疏的全局二级索引行?

如何在 C# 2.0 中使用正则表达式处理 < 或 > 类型的字符串的编码

.Net 2.0 的微 ORM? [关闭]

如何对事件日志中的 .NET 2.0 错误报告消息进行故障排除?