이 두 가지 모두 컴파일 타임 상수 여야한다는 오류를 생성합니다.
void Foo(TimeSpan span = TimeSpan.FromSeconds(2.0))
void Foo(TimeSpan span = new TimeSpan(2000))
우선 누군가 컴파일 타임에 이러한 값을 결정할 수없는 이유를 설명 할 수 있습니까? 그리고 선택적인 TimeSpan 객체의 기본값을 지정하는 방법이 있습니까?
답변
서명을 변경하면이 문제를 매우 쉽게 해결할 수 있습니다.
void Foo(TimeSpan? span = null) {
if (span == null) { span = TimeSpan.FromSeconds(2); }
...
}
자세히 설명해야합니다-예제의 표현식이 컴파일 타임 상수가 아닌 이유는 컴파일 타임에 컴파일러가 TimeSpan.FromSeconds (2.0)을 실행하고 결과 바이트를 컴파일 된 코드에 넣을 수 없기 때문입니다.
예를 들어 DateTime.Now를 대신 사용하려고했는지 고려하십시오. DateTime.Now의 값은 실행될 때마다 변경됩니다. 또는 TimeSpan.FromSeconds가 중력을 고려했다고 가정하십시오. 터무니없는 예제이지만 컴파일 타임 상수 규칙은 TimeSpan.FromSeconds가 결정적이라는 것을 알기 때문에 특별한 경우를 만들지 않습니다.
답변
내 VB6 유산은 “널 값”과 “결측 값”을 동등한 것으로 간주한다는 생각으로 인해 불편합니다. 대부분의 경우 문제는 없지만, 의도하지 않은 부작용이 있거나 예외적 인 조건을 삼킬 수 있습니다 (예 : 소스 span
가 null이 아니어야하지만 속성이 아닌 속성 또는 변수 인 경우).
따라서 메서드를 오버로드합니다.
void Foo()
{
Foo(TimeSpan.FromSeconds(2.0));
}
void Foo(TimeSpan span)
{
//...
}
답변
이것은 잘 작동합니다 :
void Foo(TimeSpan span = default(TimeSpan))
답변
기본값으로 사용할 수있는 값 세트는 속성 인수에 사용할 수있는 것과 같습니다. 기본값이의 내부 메타 데이터로 인코딩되기 때문 DefaultParameterValueAttribute
입니다.
컴파일 타임에 결정할 수없는 이유에 관해서. 컴파일 타임에 허용되는 값에 대한 값과 표현식은 공식 C # 언어 사양에 나열되어 있습니다 .
C # 6.0-속성 매개 변수 유형 :
속성 클래스의 위치 및 명명 된 매개 변수 유형은 다음과 같은 속성 매개 변수 유형으로 제한됩니다 .
- 다음 유형 중 하나 :
bool
,byte
,char
,double
,float
,int
,long
,sbyte
,short
,string
,uint
,ulong
,ushort
.- 유형
object
입니다.- 유형
System.Type
입니다.- 열거 형입니다.
(공개 접근성 및 중첩 유형 (있는 경우)도 공개 접근성 제공)- 위 유형의 1 차원 배열.
유형 TimeSpan
은 이러한 목록에 맞지 않으므로 상수로 사용할 수 없습니다.
답변
void Foo(TimeSpan span = default(TimeSpan))
{
if (span == default(TimeSpan))
span = TimeSpan.FromSeconds(2);
}
제공된 default(TimeSpan)
함수에 유효한 값이 아닙니다.
또는
//this works only for value types which TimeSpan is
void Foo(TimeSpan span = new TimeSpan())
{
if (span == new TimeSpan())
span = TimeSpan.FromSeconds(2);
}
제공된 new TimeSpan()
값이 유효하지 않습니다.
또는
void Foo(TimeSpan? span = null)
{
if (span == null)
span = TimeSpan.FromSeconds(2);
}
이 null
값이 함수에 유효한 값일 가능성 이 희박하다는 점을 고려하면 더 좋습니다 .
답변
TimeSpan
의 특별한 경우이며 메소드 DefaultValueAttribute
를 통해 구문 분석 할 수있는 문자열을 사용하여 지정됩니다 TimeSpan.Parse
.
[DefaultValue("0:10:0")]
public TimeSpan Duration { get; set; }
답변
나의 제안:
void A( long spanInMs = 2000 )
{
var ts = TimeSpan.FromMilliseconds(spanInMs);
//...
}
BTW
TimeSpan.FromSeconds(2.0)
가 같지 않음 new TimeSpan(2000)
-생성자가 틱을 걸립니다.