2017-06-12 15 views
1

(Of T)を使用するジェネリック関数を使用する場合と、タイプパラメータreturnType As Typeを使用する場合の違いがわかりません。また、以下に示すように、JSONストリングをオブジェクトサブタイプに変換する関数にとって最善のアプローチはありません。VB.NET:タイプ引数と汎用関数を使用する

Visual Studioでは、あらかじめサブタイプを知っているオブジェクトのプロパティにアクセスしようとすると、そのオブジェクトを目的のサブタイプにキャストしようとすると文句を言います。ただし、汎用関数アプローチを使用する場合にのみこれを実行します。

後で実装するために複数のクラスのインターフェイスに含めることができるように、関数シグネチャが十分に汎用的である必要があります。一般的なアプローチを使用しますが、引数としてタイプを渡すときに文句を言わないとき

Public Overloads Function Execute(jsonData As String, returnType As Type) As Object Implements IHandler.Execute 

    ' Deserializes the JSON to the specified .NET type. 
    Dim result = JsonConvert.DeserializeObject(jsonData, returnType) 

    ' Visual Studio does not complain, and the function still works 
    ' without the need of explicitly converting and checking: 

    ' result = TryCast(result, Response) 

    ' If result Is Nothing Then 
    ' Throw New Exception("Conversion failed") 
    ' End If 

    ' Visual Studio does not complain: 
    if result.Success Then 
     ProcessMessage(result.Message) 
    ElseIf result.Errors.length > 0 Then 
     HandleErrors(result.Errors) 
    End If 

    Return result 

End Function 


Public Overloads Function Execute(Of T)(jsonData As String) As T Implements IHandler.Execute 

    ' Deserializes the JSON to the specified .NET type. 
    Dim result = JsonConvert.DeserializeObject(Of T)(jsonData) 

    ' Visual Studio complains: 
    result = TryCast(result, Response) 

    If result Is Nothing Then 
     Throw New Exception("Conversion failed") 
    End If 

    ' Visual Studio complains: 
    if result.Success Then 
     ProcessMessage(result.Message) 
    ElseIf result.Errors.length > 0 Then 
     HandleErrors(result.Errors) 
    End If 

    Return result 

End Function 

何最善のアプローチは、両者の違いは何であり、なぜVisual Studioは、文句を言うのでしょうか?

Newtonsoft.JsonフレームワークのJsonConvertクラスを使用しています。

参考:http://www.newtonsoft.com/json/help/html/Overload_Newtonsoft_Json_JsonConvert_DeserializeObject.htm

+0

:dataResultは何ですか?オブジェクトをデシリアライズしていますが、(未知の?)データ結果の変換で結果を上書きするときに、実際にオブジェクトを使用していません。 –

+0

@RuardvanElburgそれは重大な間違いではありませんでした。それは "結果"だったはずですが、悲しいことに、解決策とは関係ありません。私は後でこのコードの一部を追加して問題をさらに強調し、それを間違って入力しました。それに気づいてくれてありがとう。 – Mayron

答えて

0

コンパイラは、一般的な機能について文句を言うが、それは一般的なものとは何の関係もありません、なぜ複数の理由があります。

Dim result = JsonConvert.DeserializeObject(Of T)(jsonData) 

私はresult.Successresult.ErrorsはT.で定義されていないと思うので、コンパイラがそのことについて文句明らかである:すべての

まず、結果変数の型はTです。 これらの機能を使用する場合は、TではなくResponseを使用してください。

また、あなたは(タイプTである)レスポンスに変数の結果をキャストしようとしている。

result = TryCast(result, Response) 

あなたは結果としてレスポンスを入力して結果をキャストすることはできません型Tであり、それは次のようになります。

result = TryCast(result, T) 

しかし、結果はすでに一般的にはT.

にキャストされているので、あなたは、すべてこの文は必要ありません:あなたはしていない場合は、オブジェクトを使用しないでください。汎用関数を使用する。常に最も特定のタイプを使用してください。

は、指定された型を持つ関数を呼び出します(jsonData)(応答の)を実行したりする機能を変更します。一般的な機能では

Public Overloads Function Execute(jsonData As String) As Response Implements IHandler.Execute 
    Dim result = JsonConvert.DeserializeObject(Of Response)(jsonData) 
+0

関数を汎用にするか、使用する型を宣言する必要があります。しかし、 'Execute(Of Response)(jsonData)'を使うことは動作しません。なぜなら、ジェネリック関数を実装するクラスから書く必要があるコードの本体は、特定の型に依存しているからです。正しいタイプ。 私はどちらか一方の方法が機能するが、他方の方法はなぜそうでないのか分かりません。 – Mayron

+0

インターフェイスを使用できます。必要なプロパティを持つインターフェイスとして結果をキャストします。 –

+0

私はすぐに例を挙げる時間がありません。私は今日後で私の答えを更新しようとします。 –