이 두 줄이 같은가요? … : 'vs'?? '?
이 두 줄에 차이가 있습니까?
MyName = (s.MyName == null) ? string.Empty : s.MyName
또는
MyName = s.MyName ?? string.Empty
업데이트 : 나는이 주제를 더 깊이 논의하는 블로그 포스트를 썼습니다. http://www.codeducky.org/properties-fields-and-methods-oh-my/
일반적으로 동일한 결과를 반환합니다. 그러나 getter가 첫 번째 예제에서는 두 번 실행되고 두 번째 예제에서는 한 번만 실행 MyName
되므로 속성 일 때 눈에 띄는 차이가 발생하는 몇 가지 경우 MyName
가 있습니다.
예를 들어, MyName
두 번 실행하면 성능 차이가 발생할 수 있습니다 .
string MyName
{
get
{
Thread.Sleep(10000);
return "HELLO";
}
}
또는 상태 저장 인 MyName
경우 두 번 실행하면 다른 결과를 얻을 수 있습니다 MyName
.
private bool _MyNameHasBeenRead = false;
string MyName
{
get
{
if(_MyNameHasBeenRead)
throw new Exception("Can't read MyName twice");
_MyNameHasBeenRead = true;
Thread.Sleep(10000);
return "HELLO";
}
}
또는 다른 스레드에서 변경 MyName
될 MyName
수있는 경우 두 번 실행하면 다른 결과를 얻을 수 있습니다.
void ChangeMyNameAsync()
{
//MyName set to null in another thread which makes it
//possible for the first example to return null
Task.Run(() => this.MyName = null);
}
string MyName { get; set; }
실제 코드가 컴파일되는 방법은 다음과 같습니다. 먼저 삼항식이있는 조각 :
IL_0007: ldloc.0 // s
IL_0008: callvirt s.get_MyName <-- first call
IL_000D: brfalse.s IL_0017
IL_000F: ldloc.0 // s
IL_0010: callvirt s.get_MyName <-- second call
IL_0015: br.s IL_001C
IL_0017: ldsfld System.String.Empty
IL_001C: call set_MyName
다음은 null-coalescing 연산자가있는 부분입니다.
IL_0007: ldloc.0 // s
IL_0008: callvirt s.get_MyName <-- only call
IL_000D: dup
IL_000E: brtrue.s IL_0016
IL_0010: pop
IL_0011: ldsfld System.String.Empty
IL_0016: call s.set_MyName
보시다시피 삼항 연산자에 대한 컴파일 된 코드는 속성 값을 얻기 위해 두 번의 호출을 수행하는 반면 null 통합 연산자는 1 만 수행합니다.
속성이 단순한 getter 이상인 경우 첫 번째 항목에 대해 null이 아닌 경우 함수를 두 번 실행할 수 있습니다.
속성이 상태 저장 객체에있는 경우 속성에 대한 두 번째 호출은 다른 결과를 반환 할 수 있습니다.
class MyClass
{
private IEnumerator<string> _next = Next();
public MyClass()
{
this._next.MoveNext();
}
public string MyName
{
get
{
var n = this._next.Current;
this._next.MoveNext();
return n;
}
}
public static IEnumerator<string> Next()
{
yield return "foo";
yield return "bar";
}
}
또한 문자열이 아닌 경우 클래스는 삼항 연산자와 다른 작업을 수행하기 위해 ==를 오버로드 할 수 있습니다. 삼항 연산자가 오버로드 될 수 있다고 생각하지 않습니다.
The only difference is whether you evaluate s.MyName
twice or once. The first will do it twice in the case that s.MyName
is not null, the second will only ever evaluate it once.
In most cases, this difference doesn't matter, and I'd go with the second because it's more clear and concise.
Yes, both are the same, and it is the null-coalescing operator.
It returns the left-hand operand if the operand is not null; otherwise it returns the right hand operand.
If we talk about efficiency then
string MyName = (s.MyName == null) ? string.Empty : s.MyName;
string MyName2 = s.MyName ?? string.Empty;
If I use a dissembler then I can see that the first statement needs 19 statements to be executed by the compiler whereas the second statement required only 12 statements to be executed.
Yes, they do the same. ??
is shorthand for checking for null.
They accomplish the same task.
Only difference would be readability as to whether your coworkers or whomever is reading the code understands the syntax.
EDIT: Additionally the first option can evaluate the property MyName
twice.
No. Both are doing the same thing. Second one is efficient. Which returns the actual value if it is not null. Else the right-hand side value will be returned.
Refer this http://msdn.microsoft.com/en-us/library/ms173224.aspx
Hope this helps.
참고URL : https://stackoverflow.com/questions/21052437/are-these-two-lines-the-same-vs
'Development Tip' 카테고리의 다른 글
jQuery없이 가장 가까운 요소 찾기 (0) | 2020.10.06 |
---|---|
생성자에서 정적 최종 필드 초기화 (0) | 2020.10.06 |
Spring Boot : localhost에서 REST 컨트롤러에 액세스 할 수 없음 (404) (0) | 2020.10.06 |
[01-12] 범위가 예상대로 작동하지 않는 이유는 무엇입니까? (0) | 2020.10.06 |
열거 형 이름을 C에서 문자열로 변환하는 방법 (0) | 2020.10.06 |