[c#] C # /. NET에서 매개 변수를 nullable이 아닌 것으로 표시 하시겠습니까?

nullC # /. NET에서 전달되는 것을 방지하는 함수 매개 변수에 할당 할 수있는 간단한 특성 또는 데이터 계약이 있습니까? 이상적으로 이것은 컴파일 타임에 리터럴 null이 어디에도 사용되지 않고 런타임에 사용되지 않는지 확인합니다 ArgumentNullException.

현재 나는 다음과 같이 씁니다.

if (null == arg)
  throw new ArgumentNullException("arg");

… 내가 기대하지 않는 모든 논쟁에 대해 null.

같은 메모 Nullable<>에서 다음이 실패 하는 것과 반대되는 점이 있습니까?

NonNullable<string> s = null; // throw some kind of exception



답변

불행히도 컴파일 타임에는 사용할 수있는 것이 없습니다.

최근에 내 블로그에 게시 한 새 구조체와 변환을 사용 하는 약간의 해키 솔루션 이 있습니다.

코드 계약 이 포함 된 .NET 4.0에서는 삶이 훨씬 더 좋아질 것입니다. 실제 언어 구문과 비 null 가능성에 대한 지원이 있으면 여전히 좋지만 코드 계약은 많은 도움이 될 것입니다.

또한 MiscUtilThrowIfNull 이라는 확장 메서드가 있어 좀 더 간단합니다.

마지막으로 ” if (null == arg)“대신 ” “을 ( 를) 사용하는 이유가 if (arg == null)있습니까? 후자는 읽기가 더 쉽고 전자가 C에서 해결하는 문제는 C #에 적용되지 않습니다.


답변

이 질문에 엄청나게 늦었다는 것을 알고 있지만 C #의 최신 주요 반복이 릴리스에 가까워지고 릴리스되면 대답이 관련성이 높아질 것이라고 생각합니다. C # 8.0에서는 주요 변경 사항이 발생하고 C #은 모든 유형이 null이 아닌 것으로 간주합니다.

Mads Torgersen에 따르면 :

문제는 null 참조가 매우 유용하다는 것입니다. C #에서는 모든 참조 유형의 기본값입니다. 기본값은 무엇입니까? 변수에 할당 할 다른 값을 결정할 수있을 때까지 변수에는 어떤 다른 값이 있습니까? 채울 때까지 새로 할당 된 참조 배열을 포장 할 수있는 다른 값은 무엇입니까?

또한 때때로 null은 그 자체로 합리적인 값입니다. 때로는 필드에 값이 없다는 사실을 나타내려고합니다. 매개 변수에 “아무것도”전달하지 않아도됩니다. 그러나 때때로 강조됩니다. 그리고 여기에 문제의 또 다른 부분이 있습니다. C #과 같은 언어는 여기에서 null이 좋은 생각인지 아닌지를 표현할 수 없습니다.

따라서 Mads가 설명하는 해상도는 다음과 같습니다.

  1. 참조가 null이 아니기를 원하는 것이 더 일반적이라고 생각합니다. Nullable 참조 유형은 더 희귀 한 유형이므로 (얼마나 많은 정보를 제공 할 수있는 좋은 데이터가 없더라도) 새 주석이 필요한 유형입니다.

  2. 언어에는 이미 nullable 값 유형의 개념과 구문이 있습니다. 둘 사이의 비유는 언어 추가를 개념적으로 더 쉽고 언어 적으로 더 간단하게 만들 것입니다.

  3. 적극적으로 원한다고 결정하지 않는 한 귀찮은 null 값으로 자신이나 소비자에게 부담을주지 않는 것이 옳은 것 같습니다. Null이없는 것이 아니라 명시 적으로 옵트 인해야하는 것이어야합니다.

원하는 기능의 예 :

public class Person
{
     public string Name { get; set; } // Not Null
     public string? Address { get; set; } // May be Null
}

미리보기는 Visual Studio 2017, 15.5.4+ 미리보기에서 사용할 수 있습니다.


답변

나는 이것이 아주 오래된 질문이라는 것을 알고 있지만 이것은 여기에서 누락되었습니다.

ReSharper / Rider를 사용하는 경우 Annotated Framework를 사용할 수 있습니다 .

편집 : 나는이 대답에 대해 무작위 -1을 얻었습니다. 괜찮아. 다만 그것이 알고 아직도 그것을 # 8.0 + 프로젝트를 더 이상 C의 권장 방식 아니더라도, 유효 (참조, 이유를 이해하는 그렉의 답변을 ).


답변

엔터프라이즈 라이브러리에서 유효성 검사기를 확인하십시오. 다음과 같이 할 수 있습니다.

private MyType _someVariable = TenantType.None;
[NotNullValidator(MessageTemplate = "Some Variable can not be empty")]
public MyType SomeVariable {
    get {
        return _someVariable;
    }
    set {
        _someVariable = value;
    }
}

그런 다음 코드에서 유효성을 검사하려는 경우 :

Microsoft.Practices.EnterpriseLibrary.Validation.Validator myValidator = ValidationFactory.CreateValidator<MyClass>();

ValidationResults vrInfo = InternalValidator.Validate(myObject);


답변

가장 예쁘지는 않지만 :

public static bool ContainsNullParameters(object[] methodParams)
{
     return (from o in methodParams where o == null).Count() > 0;
}

ContainsNullParameters 메서드에서도 더 창의적인 결과를 얻을 수 있습니다.

public static bool ContainsNullParameters(Dictionary<string, object> methodParams, out ArgumentNullException containsNullParameters)
       {
            var nullParams = from o in methodParams
                             where o.Value == null
                             select o;

            bool paramsNull = nullParams.Count() > 0;


            if (paramsNull)
            {
                StringBuilder sb = new StringBuilder();
                foreach (var param in nullParams)
                    sb.Append(param.Key + " is null. ");

                containsNullParameters = new ArgumentNullException(sb.ToString());
            }
            else
                containsNullParameters = null;

            return paramsNull;
        }

물론 인터셉터 또는 리플렉션을 사용할 수 있지만 오버 헤드가 거의없이 따라 가거나 사용하기 쉽습니다.


답변

Ok이 답변은 조금 늦었지만 여기에 해결 방법이 있습니다.

public static string Default(this string x)
{
    return x ?? "";
}

이 확장 방법을 사용하면 null 및 빈 문자열을 동일한 것으로 처리 할 수 ​​있습니다.

if (model.Day.Default() == "")
{
    //.. Do something to handle no Day ..
}

모든 곳에서 default를 호출해야한다는 것을 기억해야하므로 이상적이지는 않지만 하나의 솔루션입니다.


답변