이 코드 줄에서 실행:
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
두 개의 물음표는 무엇을 의미합니까? 일종의 삼항 연산자입니까? 구글에서 찾기 힘드네요.
질문자 :Edward Tanguay
이 코드 줄에서 실행:
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
두 개의 물음표는 무엇을 의미합니까? 일종의 삼항 연산자입니까? 구글에서 찾기 힘드네요.
이것은 null 병합 연산자이며 삼항(즉시-if) 연산자와 매우 유사합니다. 또한 참조 ?? 운영자 - MSDN .
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
확장:
FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();
다음으로 확장됩니다.
if(formsAuth != null) FormsAuth = formsAuth; else FormsAuth = new FormsAuthenticationWrapper();
영어로 "왼쪽에 있는 것이 null이 아니면 그것을 사용하고, 그렇지 않으면 오른쪽에 있는 것을 사용하라"는 의미입니다.
이 중 원하는 수를 순서대로 사용할 수 있습니다. 다음 명령문은 첫 번째 null이 아닌 Answer#
을 Answer
할당합니다(모든 Answers가 null이면 Answer
도 null입니다):
string Answer = Answer1 ?? Answer2 ?? Answer3 ?? Answer4;
또한 위의 확장은 개념적으로 동일하지만 각 표현식의 결과는 한 번만 평가된다는 점을 언급할 가치가 있습니다. 예를 들어 표현식이 부작용이 있는 메서드 호출인 경우 이는 중요합니다. (이 점을 지적한 @Joey에게 감사를 표합니다.)
아직 아무도 마법의 단어를 말하지 않았기 때문에 null 병합 연산자 입니다. C# 3.0 언어 사양 의 섹션 7.12에 정의되어 있습니다.
특히 표현식에서 여러 번 사용될 때 작동하는 방식 때문에 매우 편리합니다. 형식의 표현:
a ?? b ?? c ?? d
식의 결과를 줄 것이다 a
null 이외 인 경우에 그렇지 않은 시도 b
시도 그렇지 c
시도 달리 d
. 모든 지점에서 단락됩니다.
d
의 형식이 nullable이 아닌 경우 전체 표현식의 형식도 nullable이 아닙니다.
null 병합 연산자입니다.
http://msdn.microsoft.com/en-us/library/ms173224.aspx
예, 이름을 모르면 검색이 거의 불가능합니다! :-)
편집: 그리고 이것은 다른 질문의 멋진 기능입니다. 당신은 그들을 사슬로 묶을 수 있습니다.
감사합니다. MSDN 사이트에서 찾은 가장 간결한 설명은 다음과 같습니다.
// y = x, unless x is null, in which case y = -1. int y = x ?? -1;
두 개의 물음표(??)는 병합 연산자를 나타냅니다.
병합 연산자는 체인에서 첫 번째 NON-NULL 값을 반환합니다. 모든 것을 실제로 보여 주는 이 youtube 비디오 를 볼 수 있습니다.
그러나 비디오가 말하는 것에 더 추가하겠습니다.
병합의 영어 의미를 보면 "함께 통합"이라고 말합니다. 예를 들어 아래는 4개의 문자열을 연결하는 간단한 병합 코드입니다.
경우에 따라서 str1
있다 null
그것을 시도 할 것이다 str2
경우, str2
있다 null
그것을 시도 할 것이다 str3
하고 그래서 null이 아닌 값을 가진 문자열을 찾을 때까지합니다.
string final = str1 ?? str2 ?? str3 ?? str4;
간단히 말해서 병합 연산자는 체인에서 첫 번째 NON-NULL 값을 반환합니다.
??
값이 null일 때 nullable 형식에 대한 값을 제공하기 위한 것입니다. 따라서 FormsAuth가 null이면 새 FormsAuthenticationWrapper()를 반환합니다.
삼항 연산자의 약자입니다.
FormsAuth = (formsAuth != null) ? formsAuth : new FormsAuthenticationWrapper();
또는 삼항을하지 않는 사람들을 위해 :
if (formsAuth != null) { FormsAuth = formsAuth; } else { FormsAuth = new FormsAuthenticationWrapper(); }
Ruby에 익숙하다면 ||=
가 C#의 ??
나에게. 다음은 Ruby입니다.
irb(main):001:0> str1 = nil => nil irb(main):002:0> str1 ||= "new value" => "new value" irb(main):003:0> str2 = "old value" => "old value" irb(main):004:0> str2 ||= "another new value" => "old value" irb(main):005:0> str1 => "new value" irb(main):006:0> str2 => "old value"
그리고 C#에서:
string str1 = null; str1 = str1 ?? "new value"; string str2 = "old value"; str2 = str2 ?? "another new value";
병합 연산자
그것은 동등하다
FormsAuth = formsAUth == null ? new FormsAuthenticationWrapper() : formsAuth
이것에 대해 위험한 것은 없습니다. 사실, 그것은 아름답습니다. 원하는 경우 기본값을 추가할 수 있습니다. 예를 들면 다음과 같습니다.
암호
int x = x1 ?? x2 ?? x3 ?? x4 ?? 0;
"null 병합 연산자"( ?? )인 수많은 답변에서 올바르게 지적했듯이, 이에 대해 "Null-conditional Operator"( ?. 또는 ?[ ) 연산자인 "Null-conditional Operator"를 확인하고 싶을 수도 있습니다. 여러 번 그것은 ?? 와 함께 사용됩니다.
멤버 액세스( ?. ) 또는 인덱스( ?[ ) 작업을 수행하기 전에 null을 테스트하는 데 사용됩니다. 이러한 연산자를 사용하면 특히 데이터 구조로 내려가는 경우 null 검사를 처리하는 코드를 덜 작성할 수 있습니다.
예를 들어:
// if 'customers' or 'Order' property or 'Price' property is null, // dollarAmount will be 0 // otherwise dollarAmount will be equal to 'customers.Order.Price' int dollarAmount = customers?.Order?.Price ?? 0;
없는 옛날 방식 ?. 그리고 ?? 이것을 하는 것은
int dollarAmount = customers != null && customers.Order!=null && customers.Order.Price!=null ? customers.Order.Price : 0;
더 장황하고 번거롭습니다.
당신의 오락을 위해서만 (당신이 모두 C# 사람이라는 것을 알고 있습니다 ;-).
나는 그것이 스몰토크에서 시작되었다고 생각합니다. 거기에서 다음과 같이 정의됩니다.
개체에서:
? anArgument ^ self
UndefinedObject(일명 nil의 클래스)에서:
? anArgument ^ anArgument
이것에는 평가(?) 버전과 평가하지 않는 버전(??)이 있습니다.
지연 초기화된 개인(인스턴스) 변수에 대한 getter-methods에서 종종 발견되며 실제로 필요할 때까지 nil로 남아 있습니다.
나는 이 스레드와 다른 많은 사람들을 모두 읽었지만 이것만큼 철저한 답변을 찾을 수 없습니다.
??를 사용하는 이유와 ??를 사용해야 하는 시기와 ??를 사용하는 방법을 완전히 이해했습니다.
Craig McMurtry ISBN 0-672-32948-4가 공개한 Windows 통신 기반
값 유형의 인스턴스에 값이 할당되었는지 여부를 알고 싶어하는 두 가지 일반적인 상황이 있습니다. 첫 번째는 인스턴스가 데이터베이스의 값을 나타내는 경우입니다. 그러한 경우, 값이 데이터베이스에 실제로 존재하는지 확인하기 위해 인스턴스를 검사할 수 있기를 원합니다. 이 책의 주제와 더 관련이 있는 다른 상황은 인스턴스가 원격 소스에서 받은 데이터 항목을 나타내는 경우입니다. 다시 말하지만, 해당 데이터 항목에 대한 값이 수신되었는지 여부를 인스턴스에서 결정하고 싶습니다.
.NET Framework 2.0은 값 형식의 인스턴스에 null을 할당하고 인스턴스의 값이 null인지 테스트하려는 경우와 같은 경우를 제공하는 일반 형식 정의를 통합합니다. 해당 제네릭 형식 정의는 T를 대체할 수 있는 제네릭 형식 인수를 값 형식으로 제한하는 System.Nullable<T>
System.Nullable<T>
에서 생성된 형식의 인스턴스에는 null 값을 할당할 수 있습니다. 실제로 해당 값은 기본적으로 null입니다. System.Nullable<T>
에서 생성된 형식을 nullable 값 형식이라고 할 수 있습니다. System.Nullable<T>
에는 인스턴스 값이 null이 아닌 경우 생성된 형식의 인스턴스에 할당된 값을 얻을 수 있는 Value 속성이 있습니다. 따라서 다음과 같이 쓸 수 있습니다.
System.Nullable<int> myNullableInteger = null; myNullableInteger = 1; if (myNullableInteger != null) { Console.WriteLine(myNullableInteger.Value); }
System.Nullable<T>
에서 생성된 형식을 선언하기 위한 축약된 구문을 제공합니다. 이 구문을 사용하면 다음을 축약할 수 있습니다.
System.Nullable<int> myNullableInteger;
에게
int? myNullableInteger;
컴파일러는 nullable 값 형식의 값을 다음과 같은 방식으로 일반 값 형식에 할당하는 것을 방지합니다.
int? myNullableInteger = null; int myInteger = myNullableInteger;
nullable 값 형식이 null 값을 가질 수 있기 때문에 그렇게 하는 것을 방지합니다. null 값은 이 경우 실제로 가질 수 있으며 해당 값을 일반 값 형식에 할당할 수 없습니다. 컴파일러는 이 코드를 허용하지만,
int? myNullableInteger = null; int myInteger = myNullableInteger.Value;
액세스 시도가 있기 때문에 두 번째 문은 예외가 발생하는 원인이 System.Nullable<T>
로 구성 유형 경우 .Value 속성이 잘못된 작업입니다 System.Nullable<T>
T의 유효한 값이 할당되지 않은, 이 경우에는 발생하지 않았습니다.
nullable 값 형식의 값을 일반 값 형식에 할당하는 적절한 방법 중 하나는 System.Nullable<T>
.HasValue 속성을 사용하여 유효한 T 값이 nullable 값 형식에 할당되었는지 확인하는 것입니다.
int? myNullableInteger = null; if (myNullableInteger.HasValue) { int myInteger = myNullableInteger.Value; }
또 다른 옵션은 다음 구문을 사용하는 것입니다.
int? myNullableInteger = null; int myInteger = myNullableInteger ?? -1;
일반 정수 myInteger에 nullable 정수 "myNullableInteger"의 값이 할당되는 경우, 후자가 유효한 정수 값으로 할당된 경우; 그렇지 않으면 myInteger에 -1 값이 할당됩니다.
병합을 사용하여 값을 얻는 몇 가지 예는 비효율적입니다.
당신이 정말로 원하는 것은:
return _formsAuthWrapper = _formsAuthWrapper ?? new FormsAuthenticationWrapper();
또는
return _formsAuthWrapper ?? (_formsAuthWrapper = new FormsAuthenticationWrapper());
이렇게 하면 개체가 매번 다시 생성되지 않습니다. 개인 변수가 null로 남아 있고 모든 요청에 대해 새 객체가 생성되는 대신 새 객체가 생성될 때 개인 변수가 할당되도록 합니다.
다른 사람들은 Null Coalescing Operator
아주 잘 설명했습니다. null에 대한 단일 테스트가 필요한 경우 단축 구문 ??=
을 사용하면 가독성을 높일 수 있습니다.
기존 null 테스트:
if (myvariable == null) { myvariable = new MyConstructor(); }
Null 병합 연산자를 사용하여 다음과 같이 작성할 수 있습니다.
myvariable = myvariable ?? new MyConstructor();
단축 구문으로도 작성할 수 있습니다.
myvariable ??= new MyConstructor();
일부는 더 읽기 쉽고 간결합니다.
삼항 연산자와 유사하게 작동하는 null 병합 연산자입니다.
a ?? b => a !=null ? a : b
이것에 대한 또 다른 흥미로운 점은 "nullable 형식은 값을 포함할 수 있거나 정의되지 않을 수 있습니다" 입니다. 따라서 nullable 값 형식을 nullable이 아닌 값 형식에 할당하려고 하면 컴파일 시간 오류가 발생합니다.
int? x = null; // x is nullable value type int z = 0; // z is non-nullable value type z = x; // compile error will be there.
그래서 그것을 사용하여 ?? 운영자:
z = x ?? 1; // with ?? operator there are no issues
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
와 동등하다
FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();
그러나 그것에 대한 멋진 점은 다른 사람들이 말했듯이 체인을 연결할 수 있다는 것입니다. 다루지 않은 얇은 부분은 실제로 예외를 throw하는 데 사용할 수 있다는 것입니다.
A = A ?? B ?? throw new Exception("A and B are both NULL");
??
연산자를 널 병합 연산자라고 합니다. 피연산자가 null이 아니면 왼쪽 피연산자를 반환합니다. 그렇지 않으면 오른쪽 피연산자를 반환합니다.
int? variable1 = null; int variable2 = variable1 ?? 100;
설정 variable2
의 값으로 variable1
, 경우 variable1
NULL이 아닌; 그렇지 variable1 == null
variable2
를 100으로 설정하십시오.
가장 간단한 방법으로 두 개의 물음표를 "통합 연산자"라고 하며, 이는 체인에서 null이 아닌 첫 번째 값을 반환합니다.
예를 들어 nullable이 아닌 변수에서 nullable 개체에서 값을 가져오는 경우 이 연산자를 사용할 수 있습니다. 즉
정수 = 1;
인트? b = 널;
a = b??0;
b가 null이고 ??를 사용했기 때문에 위 방정식의 결과는 0이 됩니다. 연산자는 0과 함께 사용됩니다. 즉, b가 null인 경우에만 0을 반환합니다.
정수 = 1;
인트? b = 15;
a = b??0;
위의 방정식에서 b는 유효한 값을 갖고 null이 아니기 때문에 값 "15"를 얻습니다. 또한, 당신은 사용할 수 없습니다 ?? nullable이 아닌 개체에 대한 연산자입니다.
위의 예에서는 ??를 사용했습니다. 0, 그러나 완전한 새로운 방정식은 ?? 뒤에도 사용할 수 있습니다. 운영자.
와 같은
a = b ?? ( x==1 ? 10 : 15 )
귀하의 질문이 해결되기를 바랍니다.
출처 : http:www.stackoverflow.com/questions/446835/what-do-two-question-marks-together-mean-in-c
Vim에서 대소문자를 구분하지 않는 검색을 수행하는 방법 (0) | 2022.01.02 |
---|---|
Git에서 로컬 커밋 버리기 (0) | 2022.01.02 |
목록 항목의 발생 횟수를 어떻게 계산합니까? (0) | 2022.01.02 |
상속보다 구성을 선호합니까? (0) | 2022.01.02 |
TypeScript는 무엇이며 JavaScript 대신 사용하는 이유는 무엇입니까? [닫은] (0) | 2022.01.02 |