Nullable <DateTime>과 함께 DateTime.TryParse를 어떻게 사용합니까?


115

DateTime.TryParse 메서드를 사용하여 문자열의 datetime 값을 Nullable로 가져오고 싶습니다. 그러나 이것을 시도하면 :

DateTime? d;
bool success = DateTime.TryParse("some date text", out (DateTime)d);

컴파일러는 나에게 말한다

'out'인수는 변수로 분류되지 않습니다.

여기서 무엇을해야하는지 잘 모르겠습니다. 나는 또한 시도했다 :

out (DateTime)d.Value 

그리고 그것도 작동하지 않습니다. 어떤 아이디어?

답변:


123
DateTime? d=null;
DateTime d2;
bool success = DateTime.TryParse("some date text", out d2);
if (success) d=d2;

(더 우아한 솔루션이있을 수 있지만 위와 같이 간단히 수행하지 않는 이유는 무엇입니까?)


3
당신 말이 맞아, 나는 그것을 끝내기 위해 더 많은 한 줄의 라이너를 찾고 있었지만 이것이 가능할 것이라고 생각합니다. 임시 변수를 만드는 것을 좋아하지 않고 지저분합니다. :-/이 시나리오가 더 잘 지원되어야하는 것 같습니다.
Brian Sullivan

1
Binary Worrier의 제안을 참조하여 확장 방법으로 인라인 처리하십시오.
David Alpert

4
DateTime을 DateTime으로 캐스팅하는 이유는 무엇입니까? TryParse에 전달하기 전에 d2를 다시 케이스로 만들 필요가 없습니다.
Aaron Powell

@Slace-귀하의 제안을 반영하기 위해 답변을 업데이트했습니다.
Drew Noakes

@Jason Kealey 나는 이것이 VS2012에서 이미 도입되기를 바랍니다. 그렇지 않으면이 좋은 코드를 계속 사용해야 할 것입니다.
Pimenta 2011

161

Jason이 말했듯이 올바른 유형의 변수를 만들고 전달할 수 있습니다. 자신의 방법으로 캡슐화 할 수 있습니다.

public static DateTime? TryParse(string text)
{
    DateTime date;
    if (DateTime.TryParse(text, out date))
    {
        return date;
    }
    else
    {
        return null;
    }
}

... 또는 조건부 연산자가 마음에 들면 :

public static DateTime? TryParse(string text)
{
    DateTime date;
    return DateTime.TryParse(text, out date) ? date : (DateTime?) null;
}

또는 C # 7 :

public static DateTime? TryParse(string text) =>
    DateTime.TryParse(text, out var date) ? date : (DateTime?) null;

5
나는 아마도 The Skeet과 논쟁해서는 안되지만 ... TryParse라는 메서드가 TryParse 규칙을 따르고 부울을 반환 할 것으로 예상하기 때문에 Parse 메서드를 호출해야합니다. ;-)
Myster 2015-04-12

@Myster : 두 경우 모두 기존 규칙을 따르지 않습니다. 예전에는 실패시 예외 Parse가 반환 DateTime되고 예외가 발생 하기를 기대했던 것입니다 . 하지만 네, 원하는 것은 무엇이든 할 수 있습니다. 그리고 Noda Time에서 Parse대신 관련 방법의 이름을 지정했습니다 .
Jon Skeet 2015

1
else키워드의 최종 시점 이후 (첫 번째 예제) 불필요 if블록에 도달하지 않을 수 있습니다.
Jeppe Stig Nielsen

1
@JeppeStigNielsen : 예, 불필요합니다.하지만 대칭을 위해 스타일 적으로 선호 할 수 있습니다. (... 하나, 나는 일치하지 해요) 그냥 개인적인 취향이다
존 소총

3
@Kiquenet : else를 사용하면 하나 또는 다른 경로가 선택되고 둘 다 반환된다는 것이 더 명확 해집니다. 나는 대규모 중첩 코드에 반대하지만이 경우 IMO는 문제가되지 않습니다.
Jon Skeet

20

다음은 Jason이 제안한 내용에 대한 약간 간결한 버전입니다.

DateTime? d; DateTime dt;
d = DateTime.TryParse(DateTime.Now.ToString(), out dt)? dt : (DateTime?)null;

18

Nullable<DateTime>은 (는) 다른 유형 이기 때문에 할 수 없습니다 DateTime. 이를 수행하려면 자체 함수를 작성해야합니다.

public bool TryParse(string text, out Nullable<DateTime> nDate)
{
    DateTime date;
    bool isParsed = DateTime.TryParse(text, out date);
    if (isParsed)
        nDate = new Nullable<DateTime>(date);
    else
        nDate = new Nullable<DateTime>();
    return isParsed;
}

도움이 되었기를 바랍니다 :)

편집 : "this"매개 변수를 변경하려는 확장 메서드가 값 형식에서 작동하지 않기 때문에 (분명히) 부적절하게 테스트 된 확장 메서드를 제거했습니다.

PS 문제의 나쁜 후 어는 오랜 친구입니다 :)


Ya dont wanna init the date [as you 're using it as an out param] OK, I 'll stop to picky!
Ruben Bartelink

나에 대한 컴파일러는 없지만 DateTime은 값 유형이므로 확장 메서드 def가 컴파일됩니까?
Ruben Bartelink

결과가 나오지 않으면 결과가 나오지 않습니다.-[TestFixture] public class WhenExtending {[Test] public void TryParseShouldWork () {DateTime? x = null; var res = Externders.TryParse (x, "1/1/1990"); Assert.IsTrue (res)
Ruben Bartelink

; Assert.That (x! = null); }}은 Assert에서 실패합니다. 즉, DateTime이 값 유형이므로 결과가 수정되지 않습니다 (전화 화면에서 항상 좋은 제거 질문입니다 : D)
Ruben Bartelink

(obv 첫 번째 (비 확장)는 작동하지만 ref가 아닌 out이어야합니다. 일반적으로 TryXXX API에 적합하지 않으면 결과를 무효화해야합니다.-FDG에서이를 언급합니다. 난 까다 롭다
Ruben Bartelink

4

확장 방법을 만드는 것은 어떻습니까?

public static class NullableExtensions
{
    public static bool TryParse(this DateTime? dateTime, string dateString, out DateTime? result)
    {
        DateTime tempDate;
        if(! DateTime.TryParse(dateString,out tempDate))
        {
            result = null;
            return false;
        }

        result = tempDate;
        return true;

    }
}

2
첫 번째 매개 변수는 무엇입니까 dateTime? 사용되지 않습니다.
Mike Zboray

1
@mikez-이것이 확장 메서드가 작동하는 방식이며 컴파일러가 확장 메서드 여야한다는 것을 알기 위해 사용합니다.
Erik Funkenbusch 2013

3
@MystereMan 나는 확장 방법이 무엇인지 알고 있습니다. 확장 메서드에 대한 더 적절한 서명은 DateTime? TryParse(this string dateString). 이 구현은 기괴합니다.
Mike Zboray 2013

3
@mikez-그렇다면 왜 그것이 무엇인지 물어 보셨습니까? datetime에만 필요할 때 문자열 네임 스페이스를 오염시키는 이유는 무엇입니까? 목적은 DateTime.TryParse에 아날로그를 제공하는 것입니다. DateTime? .TryParse
Erik Funkenbusch

1
@ErikFunkenbusch이 확장 메서드는 또는 같은 호출 구문을 허용 하지 않습니다 . 그래서 마이크 z가 옳습니다. 이것은 방법에 대한 어리석은 서명입니다. (DateTime?).TryParse( ... )Nullable<DateTime>.TryParse( ... )
Jeppe Stig Nielsen

1

Microsoft가 왜 이것을 처리하지 않았는지 모르겠습니다. 이 문제를 처리하는 똑똑한 작은 유틸리티 방법 (int에 문제가 있었지만 int를 DateTime으로 바꾸는 것은 동일한 효과가 될 수 있습니다.

    public static bool NullableValueTryParse(string text, out int? nInt)
    {
        int value;
        if (int.TryParse(text, out value))
        {
            nInt = value;
            return true;
        }
        else
        {
            nInt = null;
            return false;
        }
    }

1

이것은 당신이 찾고있는 하나의 라이너입니다.

DateTime? d = DateTime.TryParse("some date text", out DateTime dt) ? dt : null;

적절한 TryParse 의사 확장 방법으로 만들고 싶다면 다음과 같이 할 수 있습니다.

public static bool TryParse(string text, out DateTime? dt)
{
    if (DateTime.TryParse(text, out DateTime date))
    {
        dt = date;
        return true;
    }
    else
    {
        dt = null;
        return false;
    }
}

@robnick 내가 말한 것과 어떻게 다른가요?
cpcolella

1
내 이전 댓글을 무시합니다 (솔루션을 찬성했습니다!). 최신 C #의 경우 null을 캐스팅해야했습니다. DateTime? d = DateTime.TryParse (blah, out DateTime dt)? dt : (DateTime?) null;
robnick

1

다음은 한 줄 솔루션입니다.

DateTime? d = DateTime.TryParse("text", out DateTime parseDate) ? parseDate : (DateTime?)null;

-3

또는 발생 가능한 예외에 대해 염려하지 않는 경우 TryParse for Parse를 변경할 수 있습니다.

DateTime? d = DateTime.Parse("some valid text");

성공을 나타내는 부울도 없지만 입력 텍스트가 항상 유효하다는 것을 알고있는 일부 상황에서는 실용적 일 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.