我在 VS 2012 中编写了一个默认目标为 .Net 4.5 的程序,后来有人问我需要什么绝对最小的 .Net 版本。重新定位 4.0 没有出现任何错误,尽管 3.5 和更早的版本起初似乎不太兼容。但我确信我没有使用任何“根本上”的新功能,因为我刚从 VS 2005 开始(嗯,可能是几个 LINQ 语句可以很容易地转换成循环)。换句话说,这些“新”功能都没有超出“语法/运行时糖”,如果只有微软愿意,可以在早期的 .Net 版本中实现,或者可以手动实现。
最常用的功能是:
我想知道是否有可能以不需要重写原始代码的方式扩展系统类,并保持与新的 .Net 版本的兼容性。
取 1. String.IsNullOrWhiteSpace
我尝试添加部分类定义:
#If DotNet < "4.0" Then
Namespace Global.System
    <Serializable> _
    <Runtime.InteropServices.ComVisible(True)> _
    Partial Public NotInheritable Class [String]
        Inherits Object
        Public Shared Function IsNullOrWhiteSpace(ByVal sText As String) As Boolean
            Return String.IsNullOrEmpty(sText) OrElse String.IsNullOrEmpty(sText.Trim)
        End Function
    End Class
End Namespace
#End If
那完全没有效果。我知道,可以在任意类中定义这样的函数,然后将其称为StringUtil.IsNullOrWhiteSpace(...),但仍在寻找替代解决方案。
取 2. operator =(System.Type, System.Type)
由于 .Net 4.0 之前的版本没有为 Type 类实现“=”运算符,因此无法在Select Case( switch) 构造中使用它。所以我再次尝试:
#If DotNet < "4.0" Then
Namespace Global.System
    <Serializable> _
    Partial Public MustInherit Class [Type]
        Inherits Reflection.MemberInfo
        Public Shared Operator =(ByVal oType1 As Type, ByVal oType2 As Type) As Boolean
            Return oType1 Is oType2
        End Operator
        Public Shared Operator <>(ByVal oType1 As Type, ByVal oType2 As Type) As Boolean
            Return oType1 IsNot oType2
        End Operator
    End Class
End Namespace
#End If
它也没有帮助,但确实有一些额外的效果:当这个块被隐藏时,只显示“Operator '=' is not defined for types 'System.Type' and 'System.Type'”编译器错误,但是然后它存在,然后出现其他错误,例如“'IsEnum'不是'System.Type'的成员”和我最喜欢的“类型'System.Type'的值无法转换为'System.Type'”。怎么可能同时用我的部分定义替换了真正的 System.Type,但仍然没有看到“=”和“<>”运算符的定义?
是的,我知道,我可以恢复到老式的风格:
Select Case True
    Case Is TypeOf obj Is t1
        ' ...
    Case Is (TypeOf obj Is t2) OrElse (TypeOf obj is t3)
        ' ...
End Select
但这真的很难看,我一直讨厌它。有没有办法用旧的 .Net 版本保留新的易读风格?