Dapper :이 두 코드의 차이점은 무엇입니까?

c# dapper

문제

Dapper에 대한 사용자 지정 형식 처리기를 등록하여 문자열을 serialize합니다. 이것은 예상대로 작동합니다. 그러나 코딩하는 동안 리팩토링 후 두 조각의 코드를 발견했습니다. 후자는 데이터 유형 핸들러를 트리거하지 않았지만 제 의견으로는 차이가 있습니까?

먼저 예상대로 작동하는 코드 - 사용자 정의 유형 핸들러가 dapper에 의해 호출되고 테이블에 삽입 될 때 데이터가 직렬화됩니다.

if (val.GetType() != typeof (String))
{
    var v = new JsonString {Value = val};
    this.Connection.Execute("insert into misc (k,v) values (@keyName, @v)", 
        new { keyName, v });
}
else
{
    this.Connection.Execute("insert into misc (k,v) values (@keyName, @val)", 
        new { keyName, val });
}

이제는 직렬화 된 데이터 대신 정규화 된 형식의 문자열을 테이블에 삽입 할 때 코드가 작동하지 않지만 의미 상으로는 유사하다고 생각합니다.

var v = val.GetType() != typeof (String)
        ? new JsonString {Value = val}
        : val;

// t is set to type of JsonString, therefore the dapper type handler should be used
var t = v.GetType();

this.Connection.Execute("insert into misc (k,v) values (@keyName, @v)", 
    new { keyName, v });

그것은 이상한 버그 또는 ac # oddness입니까? 필자는 실패 지점 인 3 진 조건부에서 자동 입력과 관련이 있다고 가정합니다. 그러나 t 는 Dapper (또는 사용자 정의 유형 처리기)에 의해 직렬화되는 데이터 유형으로 설정됩니다. 차이점이 뭐야?

수락 된 답변

나는 val 의 컴파일 타임 타입 (즉, 선언 타입)이 System.Object 라고 가정 할 것이다. 왜 두 가지 상황이 동일하지 않은지 설명해 드리겠습니다.

변수의 컴파일 타임 타입과 .GetType() 의해 발견되는 실제 런타임 타입을 구별하는데주의를 기울여야한다.

첫 번째 코드에서 val 이 런타임에 String 이 아닌 분기에서 다음과 같이 선언합니다.

var v = new JsonString {Value = val};

여기에서 varJsonString 의해 대체됩니다. JsonStringvar= 할당의 오른쪽 부분의 컴파일 타임 유형이기 때문입니다. 그런 다음 익명 형식 인스턴스 :

new { keyName, v }

멤버가 될 class Anonymous1 라고 부름)가 될 것입니다.

public JsonString v { get { ... } }

이제 코드의 두 번째 부분에서 대신 다음을 수행합니다.

var v = val.GetType() != typeof (String)
        ? new JsonString {Value = val}
        : val;

삼항 연산자에 대한 피연산자의 컴파일 타임 유형은 다음과 같습니다.

{bool} ? {JsonString} : {object}

컴파일시에는 JsonStringobject 가장 적합한 공통 유형을 JsonString 합니다. 그 일반적인 유형은 object 입니다. 그래서 object 는 여기서 v 의 컴파일 타임 타입이됩니다. 즉, var 는 여기에 object 의미 object .

그런 다음 익명 유형 :

new { keyName, v }

"제 2"속성을 읽는 " Anonumous2 "유형입니다.

public object v { get { ... } }

그래서 요약하기 : 당신이 속성이있는 객체를 전달 첫 번째 경우 v A와 선언 JsonString 검색된 반환 JsonSting 런타임이 일어나는 JsonString . 두 번째 코드 예제에서는 속성이있는 객체를 전달 v 로 선언 된 object 수익을 검색 object 실행시의 형태가 일어나는 JsonString .

Dapper가 어떻게 작동하는지 나는 많이 모른다! 그러나 아마도 속성 유형이 object 라는 것을 (리플렉션에 의해) 볼 때, 단순히 그 object 에 대해 .ToString() 을 호출합니다. 해당 object 가 런타임시 유형 string , string.ToString() 이 대체 string.ToString() object 는 정상이어야합니다. 그러나 JsonString.ToString() 은 그렇게하지 않습니다.

Dapper가 속성이 JsonString 으로 선언 된 것을 확인하면 Dapper는 .ToString() 호출하는 것보다 더 똑똑한 작업을 수행합니다.


인기 답변

JsonString과 String 사이에서 사용할 수있는 암시 적 변환이 없다고 가정하면 두 번째 예제의 코드는 작동하지 않습니다. 사용 가능한 암시 적 변환이있는 경우 발생한 예외에 대한 자세한 정보를 제공해야합니다.

JsonString과 JsonString 사이에 변환을 사용할 수없는 경우 유형 var로 선언 된 변수에는 컴파일러에서 유추되는 유형이 있습니다 (( https://msdn.microsoft.com/en-us/library/bb384061.aspx )).이 경우 변수 v 할당의 일부분에 따라 JsonString 또는 String 유형 중 하나입니다. 컴파일러가 JsonString 유형으로 가정하면 String을 사용한 모든 할당이 실패합니다.

두 번째 코드 예제에서는 첫 번째 코드 줄이 잘못되었으므로 두 개의 서로 다른 데이터 형식이 변수 v에 할당됩니다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow