new와 default
new는 generic 함수의 제약 조건이다. 해당 제약 조건을 걸면 generic 함수 내에서 new T()와 같은 코드를 사용할 수 있다. 이 제약 조건을 걸었을 경우 struct와 enum은 항상 사용 가능하고, class는 구현에 따라 달라지게 된다.
default는 C#의 기본 키워드로 제약 조건이 필요하지 않고, 다른 많은 곳에서도 사용할 수 있는 기능이다. default를 각 타입에 사용할 경우 아래 표와 같은 값이 생성된다.
class
class는 참조 타입(reference type)이기 때문에 null을 허용하기에 default를 사용했을 때 값은 항상 null이 된다.
new의 경우 생성자를 하나도 만들지 않은 상태라면, 항상 사용이 가능하다(기본 생성자). 반대로 매개 변수가 있는 생성자만 있을 때는 사용할 수 없다.
public class ClassDefault1
{
public int item1 { get; set; }
public string item2;
}
public class ClassDefault2
{
public int item1 { get; set; }
public string item2;
public ClassDefault2(int item1Value)
{
item1 = item1Value;
}
}
class Program
{
public static TRefType GetDefault<TRefType>()
where TRefType : new() => new TRefType();
static void Main(string[] args)
{
var cls = GetDefault<ClassDefault1>();
// ClassDefault1 { item1 = 0, item2 = null }
var cls2 = GetDefault<ClassDefault2>();
// Error CS0310
}
}
struct
값 타입 (value type)이다. 참조가 아니기 때문에 null을 허용하지 않는다.
public struct StructDefault {
public int item1 { get; set; }
public string item2;
public StructDefault(int i) {
item1 = i;
item2 = "";
}
}
var str = default(StructDefault);
var str2 = new StructDefault());
// str, str2 == StructDefault { item1 = 0, item2 = null }
만약 default나 new로 생성하고자 하면 각 멤버에 기본 값을 설정해주면 된다.
public struct StructDefault {
public int item1 { get; set; } = 10;
public string item2 = "test";
}
var str = default(StructDefault);
// StructDefault { item1 = 10, item2 = "test" }
enum
enum은 struct와 같은 값 타입이다. default와 new를 사용할 때 항상 '(E) 0'이 설정된다.
public enum EnumDefault1 {
Item1,
Item2,
Item3,
Item4,
}
public enum EnumDefault2 {
Item1, // 0
Item2, // 1
Item3 = 0,
Item4, // 1
}
public enum EnumDefault3 {
Item1 = 1,
Item2, // 2
Item3, // 3
Item4, // 4
}
var enm1 = default(EnumDefault1);
// EnumDefault1.Item1
var enm2 = default(EnumDefault2);
// EnumDefault2.Item1
var enm3 = default(EnumDefault3);
// 0
var newEnm = new EnumDefault1();
// EnumDefault1.Item1
EnumDefault3은 항목 중 0인 값이 없기 때문에 상수 0이 들어가게 된다. 이런 경우가 생길 수 있기 때문에 MSDN에서는 상수 0인 값이 항상 enum에 포함되는것을 권장한다.
만약 enum만 사용가능한 generic 함수를 만들고 싶다면 아래와 같은 코드를 작성하면 된다, 다만 이런 형태의 코드를 사용할 경우, 컴파일러 오류로 체크되지 않을 수 있다.
public TEnum EnumDefault<TEnum>()
where TEnum : struct, IConvertible
{
if (!typeof(TEnum).IsEnum)
{
throw new ArgumentException("TEnum must be an enumerated type");
}
return default(TEnum);
}
'프로그래밍 언어 > C#' 카테고리의 다른 글
[C#] Attribute : Obsolete - 더 이상 사용하지 않거나 그럴 예정인 코드에 대해서 (0) | 2024.12.16 |
---|---|
[C#] IsNullOrEmpty와 IsNullOrWhiteSpace의 차이점 (0) | 2024.11.10 |
[C#] 포인터 관련 unsafe fixed 키워드 (0) | 2024.05.23 |
[C#] Marshal (0) | 2024.05.22 |
[C#] 관리되는, 관리되지 않는 코드 (0) | 2024.05.22 |