programing

C#과 Java의 3진 연산자(? :)의 차이

minecode 2022. 10. 2. 14:39
반응형

C#과 Java의 3진 연산자(? :)의 차이

「C#」 「C#」 「C#」 「C#」 「C#」 연산자(3C#'Java')를할 때 C.? :를 참조해 주세요.

다음 코드 세그먼트에서 네 번째 행이 작동하지 않는 이유는 무엇입니까? 메세지가 됩니다.there is no implicit conversion between 'int' and 'string'하다 다.List

int two = 2;
double six = 6.0;
Write(two > six ? two : six); //param: double
Write(two > six ? two : "6"); //param: not object
Write(two > six ? new List<int>() : new List<string>()); //param: not object

다만, Java 에서는 같은 코드가 동작합니다.

int two = 2;
double six = 6.0;
System.out.println(two > six ? two : six); //param: double
System.out.println(two > six ? two : "6"); //param: Object
System.out.println(two > six ? new ArrayList<Integer>()
                   : new ArrayList<String>()); //param: Object

C#에 없는 언어 기능은 무엇입니까?있는 경우 추가되지 않는 이유는 무엇입니까?

C# 5 Language Specification 」섹션 7.14 를 참조하면, 다음과 같이 표시됩니다.

  • x가 X형이고 y가 Y형일 경우

    • X에서Y로가 아닌 암묵적인 변환(θ6.1)이 존재할 경우 Y는 조건식의 유형입니다.

    • X에서Y로가 아닌 Y에서X로 암묵적인 변환(θ6.1)이 존재하는 경우 X는 조건식의 유형입니다.

    • 그렇지 않으면 식 유형을 판별할 수 없으며 컴파일 시간 오류가 발생합니다.

즉, x와 y를 서로 변환할 수 있는지 여부를 확인하려고 하고 그렇지 않으면 컴파일 오류가 발생합니다.저희 같은 경우에는int ★★★★★★★★★★★★★★★★★」string명시적 또는 암묵적 변환이 없으므로 컴파일되지 않습니다.

이것을 Java 7 언어 사양 섹션 15.25와 대조해 주세요.조건 연산자:

  • 두 번째 오퍼랜드와 세 번째 오퍼랜드가 같은 유형(늘 유형일 수 있음)인 경우 조건식의 유형이 됩니다(NO).
  • 두 번째 및 세 번째 피연산자 중 하나가 원시형 T이고 다른 피연산자의 유형이 박스 변환(θ5.1.7)을 T에 적용한 결과일 경우 조건식의 유형은 T(NO)이다.
  • 두 번째 오퍼랜드와 세 번째 오퍼랜드 중 하나가 늘타입이고 다른 오퍼랜드의 유형이 참조타입일 경우 조건식의 유형은 해당 참조타입입니다.(NO)
  • 그렇지 않으면 두 번째 오퍼랜드와 세 번째 오퍼랜드의 타입이 수치 타입으로 변환 가능한 경우(「5.1.8」), (NO)가 몇 가지 있습니다.
  • 그 이외의 경우에는 제2 오퍼랜드와 제3 오퍼랜드가 각각 S1, S2 타입이다.S1에 박스 변환을 적용한 T1을, S2에 박스 변환을 적용한 T2를 S2로 한다.
    조건식의 유형은 캡처 변환('5.1.10)을 lub(T1, T2)에 적용한 결과('15.12.2.7). (YES)

그리고 섹션 15.12.2.7을 보면. 타입 인수 추론실제 인수를 기반으로 콜에 사용되는 타입으로 사용되는 공통의 조상을 찾으려 하는 것을 알 수 있습니다.ObjectObject 는 허용 가능한 인수이므로 콜은 동작합니다.

제시된 답변은 좋습니다.C#의 이 규칙은 보다 일반적인 디자인 가이드라인의 결과라고 덧붙입니다.몇 가지 선택지 중 하나에서 표현의 유형을 추론하도록 요구받으면 C#은 그 중에서 고유한 최선의 것을 선택합니다.즉, C#에게 "Giraffe, Fammal, Animal"과 같은 선택지를 주면 상황에 따라 가장 일반적인 동물 또는 가장 구체적인 기린을 선택할 수 있습니다.하지만 실제로 주어진 선택지하나를 선택해야 합니다.C#는 "내 선택은 고양이와 개 둘 중 하나니까 동물이 최선의 선택이라고 추리하겠다"고 말하지 않는다.그건 선택사항이 아니었으니까 C#은 선택할 수 없어요.

3진 연산자 C#의 경우 보다 일반적인 int 및 string 유형을 선택하려고 하지만 어느 쪽도 더 일반적인 유형을 선택하지 않습니다.C#은 오브젝트와 같이 처음부터 선택사항이 아닌 유형을 선택하는 대신 어떤 유형도 유추할 수 없다고 판단합니다.

또, 이것은 C#의 또 다른 디자인 원칙과도 일치하고 있는 것을 알 수 있습니다.잘못된 것 같으면 개발자에게 알려주세요.그 언어에는 "무슨 뜻인지 짐작하고 할 수 있으면 그럭저럭 해나갈 거야"라고 쓰여 있지 않다."여기 뭔가 헷갈리는 걸 쓴 것 같은데, 내가 말해줄게."라고 쓰여 있어요.

또한 C#은 변수에서 할당된 값으로 추론하는 것이 아니라 다른 방향으로 추론하는 것입니다.C#은 "객체 변수에 할당하고 있으므로 표현식은 개체로 변환할 수 있어야 합니다. 따라서 개체로 변환할 수 있도록 하겠습니다."라고 말하지 않습니다.오히려 C#은 "이 식에는 유형이 있어야 하며 유형이 객체와 호환된다는 것을 추론할 수 있어야 한다"고 말한다.식에 유형이 없기 때문에 오류가 발생합니다.

범용 부품에 대해서:

two > six ? new List<int>() : new List<string>()

C#에서 컴파일러는 오른쪽 표현 부분을 일반적인 유형으로 변환하려고 합니다.List<int>그리고.List<string>두 개의 다른 구성 유형으로, 하나는 다른 것으로 변환할 수 없습니다.

자바에서는 컴파일러가 변환이 아닌 공통 슈퍼 타입을 찾으려고 하기 때문에 코드 컴파일러는 와일드카드의 암묵적인 사용과 타입 삭제가 수반됩니다.

two > six ? new ArrayList<Integer>() : new ArrayList<String>()

의 컴파일 타입이 있습니다.ArrayList<?>(실제로는,ArrayList<? extends Serializable>또는ArrayList<? extends Comparable<?>>raw의 일반적인 범용 슈퍼타입과 런타임타입이 모두므로 사용 콘텍스트에 따라 달라집니다.ArrayList(일반적인 생슈퍼 타입이기 때문에)

를 들어 (직접 테스트),

void test( List<?> list ) {
    System.out.println("foo");
}

void test( ArrayList<Integer> list ) { // note: can't use List<Integer> here
                                 // since both test() methods would clash after the erasure
    System.out.println("bar");
}

void test() {
    test( true ? new ArrayList<Object>() : new ArrayList<Object>() ); // foo
    test( true ? new ArrayList<Integer>() : new ArrayList<Object>() ); // foo 
    test( true ? new ArrayList<Integer>() : new ArrayList<Integer>() ); // bar
} // compiler automagically binds the correct generic QED

Java와 C#(및 기타 대부분의 언어)에서는 식 결과에 유형이 있습니다.3차 연산자의 경우 결과에 대해 평가되는 두 가지 가능한 하위 식이 있으며 둘 다 동일한 유형을 가져야 합니다.Java의 경우,int변수 변환이 가능합니다.Integer자동 박스로요.이제 둘 다Integer그리고.String로부터 물려받다.Object단순한 압축 변환에 의해서, 같은 타입으로 변환할 수 있습니다.

한편, C#에서는int에 대한 암묵적인 변환은 없습니다.string또는 다른 것object.

이것은 꽤 간단하다.문자열과 int 사이에는 암묵적인 변환은 없습니다.ternary 연산자는 마지막 2개의 오퍼랜드가 같은 타입이어야 합니다.

시험:

Write(two > six ? two.ToString() : "6");

언급URL : https://stackoverflow.com/questions/35230846/difference-between-c-sharp-and-javas-ternary-operator

반응형