문제
다음과 같은 두 가지 방법이 포함 된 수업이 있습니다.
public String getFoo(Int32 a)
{
return getBar(a, "b", null);
}
public String getBar(Int32 a, String b, Int32 c)
{
//do something
return "";
}
그러나 수업을 컴파일하면 두 가지 오류가 발생합니다.
- getbar (int, string, int)에 대한 최고의 과부하 메소드 일치에는 몇 가지 잘못된 인수가 있습니다.
- 인수 '3': '에서 전환 할 수 없습니다'
<null>
'int'
이 오류가 발생하는 이유를 이해한다고 생각합니다. 컴파일러는 컴파일 시점에서 실제 유형의 객체가 무엇인지 알지 못합니다. 누군가가 오류의 원인에 대해 정확한지 확인하거나 실제 이유를 지적 할 수 있습니까?
더 중요한 것은이 방법으로 내 코드를 디자인 할 수 있습니까? 그렇다면 오류를 해결하려면 어떻게해야합니까? 이 방법으로 수업을 디자인 한 이유는 getfoo의 getbar에서 코드를 복제하고 싶지 않기 때문입니다. 두 가지 방법은 본질적으로 세 번째 매개 변수를 취하는 것을 제외하고는 동일합니다.
감사.
해결책
.NET에는 참조 유형과 값 유형 사이에 뚜렷한 개념이 있습니다.
참조 유형은 힙에 할당 된 객체입니다 (System.Object의 서브 클래스). 스택에있는 모든 것은이 객체에 대한 포인터입니다. 그로 인해 널 포인터를 저장하는 것은 완벽하게 유효합니다.
값 유형은 스택에 할당 된 객체이며 System.ValueType의 서브 클래스가됩니다. 값 유형이 스택에 있어야 값을 함수로 전달할 때 객체의 전체 내용을 전달합니다.
값 유형은 널가 될 수 없습니다.
대부분의 C# 원시 유형은 값 유형입니다. 문자열은 실제로 참조 유형 인 특수 유형의 원시입니다.
.NET 2.0에서 MS는 구조물 내부에 일반 유형을 동봉하여 무효 유형을 시뮬레이션 할 수있는 기능을 추가했습니다. 실제로 일어나는 일은 무효가 될 수있는 논리입니다.u003CT> Struct는 당신을 위해 널을 모방하고 있습니다.
예를 들어 유형에 물음표를 추가하여 구문 단축키를 사용하여 표현했습니다.
int? nullableInt = null;
float? nullableFloat = null;
등...
int가 마음에 들지 않으면? 구문, 항상 nullable을 사용할 수 있습니다u003CSomeType>
public String getBar(Int32 a, String b, Nullable<Int32> c)
참고로, 나는 당신이하고있는 일을 할 때 과부하를 추가하고, 구문을 더 좋게 만들기 위해 선호합니다.
public String getBar(Int32 a, String b)
{
this.getBar(a,b,null);
}
public String getBar(Int32 a, String b, Nullable<Int32> c)
{
}
다른 팁
Int32
값 유형입니다 null
유형의 매개 변수에 대한 유효한 인수가 아닙니다 Int32
.
실제로 널리 잡을 수없는 int가 필요한 경우 사용하십시오 int?
유형.
당신이보고있는 두 가지 오류는 실제로 같은 오류입니다.
Sunny가 맞습니다.
int32는 값 유형이며 값 'null'을 유지할 수 없습니다. 'null'을 매개 변수 값으로 전달 해야하는 경우 int32 대신 인수 유형으로 nullable을 사용하십시오.
더 많은 정보를 찾을 수 있습니다 Nullable 유형 (C# 프로그래밍 안내서) MSDN에서.
int32는 값/널리킹 불가능한 유형 인 int의 별칭입니다. 널리 사용 가능한 버전의 경우 시스템을 사용하십시오.
또한 널리화되지 않는 int로 다시 변환하는 것을 잊지 마십시오.
int? nullable = ...;
int non_nullable = nullable??0;
여기서 숫자는 그것이 실제로 무효인지 여부를 가정 해야하는 값을 나타냅니다.
int32는 null이 될 수 없습니다. 대신 무효 유형으로 만드십시오.
public String getBar(Int32 a, String b, Int32? c)
{
if (c.HasValue)
{
...do something with c.Value...
}
return "";
}
알았어 그래서 다섯7 명이 제안했습니다 int?
솔루션으로. 나는 두 가지 다른 솔루션을 제안합니다 ~할 것 같다 상황에 따라 더 적절해야합니다.
과부하를 만듭니다 두 개의 인수 만있는 방법의
null
전화 할 때 :public String getFoo(Int32 a) { return getBar(a, "b", null); } public String getBar(Int32 a, String b) { //do something else, without the int }
코드 복제를 피하고 싶다고 말한 이후 로이 작업을하고 싶지는 않지만
사용
default
대신에null
:return getBar(a, "b", default(int));
또한 이것은 값을 전달하는 것과 동일합니다.
0
.