programing

null 일 수있는 값을 반환하는 간단한 방법이 있습니까?

nasanasas 2020. 11. 29. 11:48
반응형

null 일 수있는 값을 반환하는 간단한 방법이 있습니까?


다음 시나리오의 약어를 어떻게 작성할 수 있습니까?

get
{
    if (_rows == null)
    {
        _rows = new List<Row>();
    }

    return _rows;
}

사용 널 유착 연산자 (??) :

get 
{ 
     _rows = _rows ?? new List<Row>(); 
     return _rows; 
}

또는 (가독성이 낮음) :

get { return _rows ?? (_rows = new List<Row>()); }

? 연산자를 null 통합 연산자라고합니다. 피연산자가 null이 아니면 왼쪽 피연산자를 반환합니다. 그렇지 않으면 오른손 피연산자를 반환합니다.


이것은 지연 초기화 패턴이므로 간단한 방법은 Lazy <T> 클래스 를 사용하는 것 입니다.

class Foo
{
    Lazy<List<Row>> _rows;

    public Foo()
    {
        _rows = new Lazy(() => new List<Row>());
    }

    public List<Row> Rows
    {
        get { return _rows.Value; }
    }
}

이것은 초기화 로직으로 게터를 "오염"시키지 않는다는 추가적인 이점이 있습니다.


삼항 연산자를 제안합니다

get {
  return _rows == null ? _rows = new List<Row>() : _rows;
}

또는 비어 있으면 List<Row>오버 헤드가 많지 않기 때문에 명시 적 _row필드를 제거 하고 읽기 전용 속성 만 구현하면됩니다 ( C # 6.0 구문).

public IList<Row> Rows {get;} = new List<Row>();

더 나은 아이디어가 있습니다. Prevent _rowsfrom ever being null.

생성자가 변수를 초기화하도록합니다.

public MyClass()
{
    this._rows = new List<Row>();
}

그리고 당신의 재산은 단지

get
{
    return this._rows;
}

변수를 "삭제"해야하는 경우 항상 해당 Clear메서드를 호출 하거나을 할당하는 대신 새로운 빈 목록을 할당해야 null합니다. 클래스 전체에 걸쳐 명확하고 일관되게 작성해야하는 경우 메서드에서 해당 작업을 인코딩 할 수 있습니다.

이것은 훨씬 더 논리적입니다. 당신의 변수는 않을 것입니다 경우 null, 그것은 않을 것입니다null . 또한 getter가 상태를 수정하는 조건 및 문제를 깔끔하게 방지합니다.


List<Row> _rows;
public List<Row> Rows => _rows ?? (_rows = new List<Row>());

다른 사람들이 말했듯이이 시나리오에서는 null 통합 연산자를 사용할 수 있습니다.

get
{
    return _rows ?? (_rows = new List<Row>());
}

이것이 ReSharper 가 제안하는 데 탁월한 변화라는 점에 주목할 가치가 있습니다 ( 빠른 수정이라고 함 ).

귀하의 예에서는 if아래에 작은 물결 모양이 표시됩니다 . 마우스를 가져 가면 코드를 변경 / 단순화 할 수있는 방법에 대한 제안이 표시 됩니다.

Convert to '??' expression

몇 번의 클릭으로 변경 사항이 구현됩니다.

enter image description here


예를 들면 다음과 같습니다.

get{ return _rows ?? (_rows = new List<Row>()); }

If you want your code to behave like your current code, lazily initialising your backing field when the property is accessed, then yes, you can make it shorter. You can rename your backing field, as answered already use ?? to put everything in a single expression, and when you have that single expression, use C# 6's new property syntax to avoid writing get and return:

List<Row>_;List<Row> Rows=>_??(_=new List<Row>());

Hopefully, well before you get to this point, you will see that you've turned easy-to-understand code that does exactly what you want into a horrible mess that you would never want to maintain.

Just keep your code exactly as it is. You can make it shorter, as shown, but that doesn't make it any better.

If the problem is that it takes more time to write, because you keep typing the same code over and over, many IDEs provide some feature to insert templates, snippets, or whatever term they use for it. This lets you define something along the lines of

{Type} {Field};
public {Type} {Property} {
  get {
    if ({Field} == null) {
      {Field} = new {Type}();
    }
    return {Field};
  }
}

where your editor will then prompt you for the specific {Type}, {Field}, {Property}, without having to type it again each time.


return _rows ?? (_rows = new List<Row>());

If you really wanted to shorten it I would just remove the extra brackets.

    get
    {
        if (_rows == null)
            _rows = new List<Row>();

        return _rows;
    }

You can do this by any of the following ways:

  • Conditional operator (?:)
  • Null-coalescing operator ( ?? )

With Conditional operator

get {
  return _rows == null ? new List<Row>() : _rows;
}

Null-coalescing operator

get { 
  return _rows ?? new List<Row>(); 
}

참고URL : https://stackoverflow.com/questions/38266880/is-there-a-shorthand-way-to-return-values-that-might-be-null

반응형