a = (x == null)? null : x.func ()
기본 질문-다음과 같은 코드 줄이 많이 있습니다.
var a = (long_expression == null) ? null : long_expression.Method();
이 기능에서는 비슷한 선이 많이 반복됩니다. long_expression매번 다릅니다. 나는 반복을 피하는 방법long_expression 을 찾고 있지만, 이것을 간결하게 유지합니다 . 의 반대와 같은 것 operator ??. 지금은 그냥 포기하고 다음과 같이 여러 줄에 넣는 것을 고려하고 있습니다.
var temp = long_expression;
var a = (temp == null) ? null : temp.Method();
그러나 내가 모르는 영리한 구문이 있으면 이것을 더 간결하게 만들 수 있는지 궁금했습니다.
음, 다음 과 같은 확장 방법을 사용할 수 있습니다.
public static TResult NullOr<TSource, TResult>(this TSource source,
Func<TSource, TResult> func) where TSource : class where TResult : class
{
return source == null ? null : func(source);
}
그때:
var a = some_long_expression.NullOr(x => x.Method());
또는 (C # 버전에 따라 다름)
var a = some_long_expression.NullOr(Foo.Method);
Foo유형은 어디에 있습니까 some_long_expression?
내가 생각하지 않는 것 이 생각을한다. 두 줄 버전을 사용합니다. 더 간단하고 덜 영리하며 스택 오버플로에서는 "영리함"이 재미 있지만 실제 코드에는 일반적으로 좋은 생각이 아닙니다.
내가 발견 이 응답 통찰력을.
이 할당을 수행하면 널을 시스템에 더 깊이 전파하게됩니다. 이러한 전파를 처리하려면 null 처리 조건을 다시 작성해야합니다.
null로 실행을 계속하는 대신 null을 더 나은 표현 (링크에서 인용)으로 대체하십시오.
- null이 빈 컬렉션을 나타내는 경우 빈 컬렉션을 사용합니다.
- null이 예외적 인 경우를 나타내는 경우 Exception을 throw합니다.
- null이 실수로 초기화되지 않은 값을 나타내는 경우 명시 적으로 초기화합니다.
- null이 합법적 인 값을 나타내는 경우 테스트하거나 null 작업을 수행하는 NullObject를 더 잘 사용합니다.
특히 null 컬렉션 참조를 빈 컬렉션으로 대체하면 많은 null 테스트가 절약되었습니다.
var x = "";
/* try null instead */
string long_expression = "foo";
var a = ((x = long_expression) == null) ? null : x.ToUpper();
/* writes "FOO" (or nothing) followed by newline */
Console.WriteLine(a);
의 초기화 값 x유형은 long_expression(여기 :) 의 유형과 호환되어야합니다 string. 와 작품 모노 C # 컴파일러 버전 2.10.8.1 (데비안에서 패키지 모노 gmcs = 2.10.8.1-4).
저는 C # 언어가 이러한 종류의 논리에 대해 새로운 연산자를 실제로 사용할 수 있다고 생각합니다. 이것은 매우 일반적이며 연산자는 수많은 코드 줄을 단순화합니다.
"??"줄을 따라 뭔가가 필요합니다. 또는 "if null then"연산자이지만 특수 '.'로 작동합니다. "null이 아닌 경우"조건이있는 도트 연산자. 처음으로 '?' "? :"if-then의 'if'부분과 두 번째 '?' nullable 형식과 같이 'null'을 나타냅니다. ".?"가 필요하다고 생각합니다. '.'처럼 작동하는 연산자입니다. 예외를 던지는 대신 왼쪽 표현식이 null 인 경우 단순히 null로 평가된다는 점만 제외하면됩니다. 나는 그것이 "널이 아닌 점"연산자 일 것이라고 생각한다 (좋아, 그래서 아마도 ".!?"가 더 논리적 일 것이지만 거기에 가지 말자).
따라서 당신의 아주 흔한 예는 다음과 같이 중복 된 기호 이름을 잃을 수 있습니다.
var a = long_expression.?Method();
큰 이점을 얻을 수있는 중첩 된 null 검사가있는 수많은 C # 코드가 있습니다. 다음과 같은 경우 얼마나 좋을지 생각해보십시오.
if (localObject != null)
{
if (localObject.ChildObject != null)
{
if (localObject.ChildObject.ChildObject != null)
localObject.ChildObject.ChildObject.DoSomething();
}
}
다음과 같이 될 수 있습니다.
localObject.?ChildObject.?ChildObject.?DoSomething();
There is also a ton of code where null checks that should be there are missing, resulting in occasional runtime errors. So, actually using the new '.?' operator by default would eliminate such problems... It's perhaps unfortunate that we couldn't reverse the behavior of '.' and '.?' at this point, so only the new '.?' throws an exception if the left side is null - it would be the cleaner and more logical way to go, but breaking changes are very bad. Although, one could argue that this particular change would be likely to fix a lot of hidden problems, and unlikely to break anything (only code that expects a null ref exception to be thrown). Oh, well... one can always dream...
The only downside to checking for the null is really the slight performance hit, which is most assuredly why '.' doesn't check for null. But, I really think the ability to just use '.?' when you care about performance (and know the left side will never be null) would have been the better way to go.
On a similar note, having 'foreach' check for and ignore a null collection would have also been so much nicer. No more need to wrap most 'foreach' statements with "if (collection != null)", or worse, develop the common habit of always using empty collections instead of null ... which is fine in some cases, but an even worse performance issue than the null check when this is done in complex object trees where the majority of the collections are empty (which I've seen a lot). I think the good intention of not having 'foreach' check for null to provide better performance has backfired in the majority of cases.
Anders, it's never too late to make such changes, and add a compiler switch to enable them!
You can write an extension method for whatever type long_expression evaluates to:
public static object DoMethod(this MyType pLongExpression)
{
return pLongExpression == null ? null : pLongExpression.Method();
}
This will be callable on any MyType reference, even if that reference is null.
You could put long_expression == null into a function with a short name and just call that function each time.
if (!String.IsNullOrEmpty(x)) x.func()
참고URL : https://stackoverflow.com/questions/11267554/best-syntax-for-a-x-null-null-x-func
'IT TIP' 카테고리의 다른 글
| Java-값으로 문자열 배열을 어떻게 만듭니 까? (0) | 2020.12.10 |
|---|---|
| 둘 이상의 디테일 뷰 컨트롤러를 푸시 할 때 "DetailViewController의 모양 전환을 시작 / 종료하기위한 불균형 호출" (0) | 2020.12.10 |
| Twitter-bootstrap 축소 플러그인-여러 "그룹"을 열려면 어떻게해야합니까? (0) | 2020.12.10 |
| 정적 변수 C ++에 대한 정의되지 않은 참조 (0) | 2020.12.10 |
| "정의로 이동"후에 당신이 어디에서 왔는지 돌아가라는 명령이 있습니까? (0) | 2020.12.10 |