방프리
24.01.01 Chapter2. API 설계 (Item 25) 본문
Item 25 : 배열 매개변수에는 params 배열만 사용해야 한다
배열은 반공변을 지원하지 않는다. 그렇기 때문에 배열형태의 매개변수를 받을 수 있는 것에 제한이 크다.
그럴 땐 IEnumerable<T> 형태로 사용하는 것이 좋다.
class B
{
public static B Factory() => new B();
public virtual void WriteType() => WriteLine("B");
}
class D1 : B
{
public static new B Factory() => new D1();
public override void WriteType() => WriteLine("D1");
}
class D2 : B
{
public static new B Factory() => new D2();
public override void WriteType() => WriteLine("D2");
}
B[] storage = new D1[10];
//모두 에러
FillArray(storage, () => B.Factory());
FillArray(storage, () => D1.Factory());
FillArray(storage, () => D2.Factory());
하지만 IEnumerable<T>는 내부 시퀸스에 있는 데이터를 수정하진 못한다. 이럴 땐 시퀸스를 인수로 받은 후 수정된 시퀸스를 반환하면 된다.
static IEnumerable<T> FillArray<T>(IEnumerable<T> storage, Func<T> factory)
{
var uniqueVals = new HashSet<T>();
foreach (var element in storage)
{
if (uniqueVals.Contains(element) == false)
{
uniqueVals.Add(factory());
yield return element;
}
}
}
static void Main()
{
B[] storage = new D1[10];
FillArray(storage, () => B.Factory());
FillArray(storage, () => D1.Factory());
FillArray(storage, () => D2.Factory());
}
순수 배열을 매개변수로 전달할 때 두 가지 문제를 야기한다. 첫 번째는 배열은 공변을 지원하므로 런타임 오류를
발생시킬 수 있다. 두 번째는 배열은 요소를 간접적으로 참조하기 때문에 매개변수로 전달받은 배열은 변경될 수 있다.
하지만 그것이 정확한지는 판단할 수는 없다 그렇기에 가변적인 배열이라면 params 배열을 사용하는 것이
좀 더 안정적이다.
'C# > More Effective C#' 카테고리의 다른 글
24.01.04 Chapter3. 태스크 기반 비동기 프로그래밍 (Item 27) (1) | 2024.01.04 |
---|---|
24.01.02 Chapter2. API 설계 (Item 26) (0) | 2024.01.02 |
23.12.17 Chapter2. API 설계 (Item 24) (1) | 2023.12.17 |
23.12.12 Chapter2. API 설계 (Item 23) (0) | 2023.12.12 |
23.11.12 Chapter2. API 설계 (Item 22) (0) | 2023.11.12 |
Comments