이 두 줄에 차이가 있습니까?
MyName = (s.MyName == null) ? string.Empty : s.MyName
또는
MyName = s.MyName ?? string.Empty
답변
업데이트 : 나는이 주제를 더 깊이 논의하는 블로그 포스트를 썼습니다. http://www.codeducky.org/properties-fields-and-methods-oh-my/
일반적으로 동일한 결과를 반환합니다. 그러나 첫 번째 예제 MyName
에서는 MyName
getter가 두 번 실행되고 두 번째 예제에서는 한 번만 실행 되기 때문에 속성 일 때 눈에 띄는 차이가 발생하는 몇 가지 경우 가 있습니다.
예를 들어, 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";
}
}
또한 문자열이 아닌 경우 클래스는 삼항 연산자와 다른 작업을 수행하기 위해 ==를 오버로드 할 수 있습니다. 삼항 연산자가 오버로드 될 수 있다고 생각하지 않습니다.
답변
유일한 차이점은 s.MyName
두 번 또는 한 번 평가하는지 여부 입니다. 첫 번째는 s.MyName
null이 아닌 경우 두 번 수행하고 두 번째는 한 번만 평가합니다.
대부분의 경우이 차이는 중요하지 않으며, 더 명확하고 간결하기 때문에 두 번째를 사용하겠습니다.
답변
예, 둘 다 동일하며 null 통합 연산자 입니다.
피연산자가 null이 아니면 왼쪽 피연산자를 반환합니다. 그렇지 않으면 오른손 피연산자를 반환합니다.
효율성에 대해 이야기하면
string MyName = (s.MyName == null) ? string.Empty : s.MyName;
string MyName2 = s.MyName ?? string.Empty;
dissembler를 사용 하면 첫 번째 명령문 은 컴파일러에서 19 개의 명령문 을 실행 해야하는 반면 두 번째 명령문은 12 개의 명령문 만 실행하면된다는 것을 알 수 있습니다.
답변
예, 그들은 똑같이합니다. ??
null 확인을위한 속기입니다.
답변
그들은 동일한 작업을 수행합니다.
유일한 차이점은 동료 또는 코드를 읽는 사람이 구문을 이해하는지 여부에 대한 가독성입니다.
편집 : 또한 첫 번째 옵션은 속성을 MyName
두 번 평가할 수 있습니다 .
답변
아뇨. 둘 다 같은 일을하고 있습니다. 두 번째는 효율적입니다. null이 아닌 경우 실제 값을 반환합니다. 그렇지 않으면 오른쪽 값이 반환됩니다.
http://msdn.microsoft.com/en-us/library/ms173224.aspx를 참조하십시오 .
도움이 되었기를 바랍니다.