1

私は VS 2012 で .Net 4.5 をデフォルトの対象とするプログラムを作成しましたが、後で絶対に必要な最小の .Net バージョンは何かと尋ねられました。4.0 への再ターゲットではエラーは発生しませんでしたが、3.5 以前のバージョンは最初はあまり互換性がないように見えました。しかし、私は VS 2005 から新しくなったので、「根本的な」新機能を使用していないことは確かにわかっていました (簡単にループに変換できる 2 つの LINQ ステートメントかもしれません)。言い換えれば、これらの「新しい」機能はいずれも、「シンタックス / ランタイム シュガー」を超えたものではなく、Microsoft だけが望むなら以前の .Net バージョンで実装できた、または手動で実装できたものではありませんでした。

最も頻繁に使用される機能は次のとおりです。

  • Enumerable.First / Enumerable.Single
  • String.IsNullOrWhiteSpace
  • operator =(System.Type, System.Type)
  • 元のコードの書き直しを必要とせず、新しい .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)

    バージョン 4.0 より前の .Net は 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
    

    どちらも役に立ちませんでしたが、追加の効果がありました。このブロックが非表示の場合、「演算子 '=' は型 'System.Type' および '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 バージョンで読みやすい新しいスタイルを保持する方法はありますか?

    4

    1 に答える 1

    1

    部分クラスを使用して、別のアセンブリ内のクラスを拡張することはできません。
    部分クラスは純粋に構文上の機能です。

    System.Type元の とは何の関係もないという新しいクラスを作成しましたSystem.Type
    そうしないでください。

    于 2012-12-05T17:13:09.903 に答える