2017-11-21 13 views
0

私はC#から来ているKotlinには初めてです。現在、私は交換可能ないくつかのジェネリック型を取るクラスをセットアップしようとしています。このクラスの内部コードはスプリングサービスのエンドポイントです。ジェネリッククラスの型での値と呼び出しメソッドの参照

私は以下のようなものから始めましたが、リクエストボディのパラメータを参照する構文と、クラスコンストラクタで渡される型のメソッドを呼び出す構文に問題があるようです。ジェネリックスやリフレクションの構文はまっすぐなものではなく、私が掘り下げたコトルリンの例の大部分は、私がしようとしていることを(たとえ可能であっても)正確にカバーしていないようです。 type1のオブジェクトインスタンスはbodyパラメーターで渡され、type2のオブジェクトインスタンスはコンストラクターを介して渡されます(構文はおそらく正しくない)。

これをテンプレートとして使用して、同じ基本コードに基づいて異なる要求およびサービスクラスを使用して複数のエンドポイントをセットアップすることを計画しています。

ご協力いただきまして誠にありがとうございます。

import org.springframework.beans.factory.annotation.Autowired 
import org.springframework.http.HttpStatus 
import org.springframework.http.ResponseEntity 
import org.springframework.web.bind.annotation.RequestBody 
import org.springframework.web.bind.annotation.RequestMapping 
import org.springframework.web.bind.annotation.RequestMethod 
import javax.validation.Valid 

open class Base <T1,T2>(t1: Class<T1>, t2: Class<T2>) { 

    @Autowired 
    var type1 = t1 

    @Autowired 
    var type2 = t2 

    @ApiOperation(value = "API 1", response = myResponse::class) 
    @ApiResponses(value = *arrayOf(
    ApiResponse(code = 200, message = "successful", response = CcdaResponse::class), 
    ApiResponse(code = 405, message = "Invalid", response = Void::class))) 
    @RequestMapping(
    value = "/myEndPoint", 
    produces = arrayOf("application/json"), 
    consumes = arrayOf("application/json"), 
    method = arrayOf(RequestMethod.POST) 
) 

    fun endpoint(
    @ApiParam(value = "Options", required = true) 
    @Valid 
    @RequestBody 
    body: Class<T1> 
): ResponseEntity<myResponse> { 
    val r = myResponse() 
    val response: ResponseEntity<myResponse> 
    response = ResponseEntity(r, HttpStatus.OK) 
    try { 

     //payload 
     val parameters = Parameters().apply { 
     Id1 = type1::body.Id1.get() 
     Id2 = type1::body.Id2.get() 
     Id3 = type1::body.Id3.get() 
     Id4 = type1::body.Id4.get() 
     v = type1::body.v.get() 
     } 
     //Do stuff like calling method in class of type2 passed in 
     val d = type2.getViewModel(parameters) 

     r.status = "ok" 

    } catch (e: Exception) { 
     r.message = e.toString() 
     r.status = "error" 
    } finally { 
    } 
    return response 
    } 
} 
+0

コンストラクタで_class_自体を渡そうとしています(おおよそ.NETの 'Type'に対応します)かインスタンスですか? "type2のオブジェクトインスタンスがコンストラクタを介して渡されるべきだ"と言っているので、 'Class '/'Class ' – Moira

+0

の代わりに 'T1' /' T2'が必要なように見えます。type1のインスタンスエンドポイント関数のbodyパラメーターと、Baseクラスのコンストラクターを介してtype2のインスタンスを使用します。私は渡された型自体が必要であると仮定し、実際のオブジェクトで3番目のパラメータが必要な場合がありますか? – aggaton

答えて

0

パラメータの型は、インスタンスを作成するとき(Javaと同じ)型引数で渡されます。したがって、型自体を渡す必要があります。Classパラメータを追加することは、正しい構文ではありません。

私はこれがあなたが探していると信じています(簡潔にするためにいくつかのコードを省略しました)。

open class Base<T1, T2> (@Autowired var t2: T2) { 

    @Autowired var type1: T1? = null 

    fun endpoint(
     @ApiParam(value = "Options", required = true) @Valid @RequestBody 
     body: T1 
    ): ResponseEntity<MyResponse> { 
     type1 = body 
    } 

} 

その後、たとえば、あなたは、次のようにタイプ(それぞれT1T2用)IntStringで、このクラスのインスタンスを作成することができます。

val t2 = "t2" 
val base = Base<Int, String>(t2) 

それとも、指定したタイプのいずれか(またはなし)でBaseクラスをサブクラス化することができます。

class SubBase(t2: String): Base<Int, String>(t2) 
+0

ありがとう、ちょうど私が探していたもの。 – aggaton

+0

1つの質問が表示されました。 type1/bodyオブジェクトの属性にアクセスするにはどうすればよいですか?コンストラクタに渡されるt2パラメータと同じです。 – aggaton

+0

@aggatonジェネリック型のプロパティにアクセスすることができます(デフォルトは 'Any Any'型になっています)。 ['is'演算子](https://kotlinlang.org/docs/reference/generics.html#type-projections)や[型予測](https://kotlinlang.org/docs)を見てみることをお勧めします。 /reference/generics.html#type-projections)を使用して、より具体的なタイプのプロパティにアクセスします。または、サブクラスまたは[オブジェクト式](https://kotlinlang.org/docs/reference/object-declarations.html#object-expressions)の関数をオーバーライドして、型引数で指定された型にアクセスできます。 – Bryan

関連する問題