목록에 항목을 추가할 때 키라던가 이름이 중복되지 않아야 할 경우가 있습니다.
항목을 추가할 때 이름이 같은지를 비교해 같은 경우 추가하지 못하게 하거나, 중복된 이름을 이름(1)
등으로 변경해서 추가하는 방법이 있는데요, 저는 후자의 경우 편리한 팁을 공유합니다.
C#은 확장 메서드를 지원합니다. 정적 클래스의 정적 메소드로 첫번째 인자를 this T @this
등으로 선언하면 마치 T 유형의 메소드처럼 쓸 수 있습니다.
확장 메소드를 이용해 IEnumerable<T>
유형일 경우 사용할 수 있는 메소드 GetUniqueName()
을 다음처럼 만들고 사용할 수 있습니다.
public static class EnumerableExtension
{
public static string GetUniqueName<T>(this IEnumerable<T> @this, string newName, Func<T, string> getNameFunc)
{
var name = newName;
var bResult = @this.Any(x => getNameFunc(x) == name);
if (bResult is false)
return newName;
var number = 1;
while (true)
{
name = $"{newName}({number})";
bResult = @this.Any(x => getNameFunc(x) == name);
if (bResult is false)
return name;
number++;
}
}
}
코드가 좀 중복되는데 코드 라인이 짧고 되려 이게 코드 가독성이 좋아 이렇게 유지를 했습니다. 좀 더 깔끔한 코드 추천 해주세요 ^^
사용할 이름을 newName
인자로 받고, GetNameFunc
를 통해 T 유형에서 이름을 얻은 후 Any()
로 비교해서 없을 경우 반환합니다.
만약, 존재할 경우 이름(1)
, 이름(2)
형태로 만들어나가며 없을때까지 확인 후 반환하게 됩니다.
사용은 다음처럼 쓸 수 있습니다.
private void AddNewDatabaseSetting()
{
DatabaseSettings.Add(new()
{
Kind = DatabaseKind.Oracle,
Name = DatabaseSettings.GetUniqueName("새 연결", x => x.Name!),
OnPropertyChangedCallback = OnChangedDatabaseSetting
});
}
만약 새 연결
이란 이름이 있을 경우 새 연결(1)
로, 이 이름도 있을 경우 새 연결(2)
이 되는 식입니다.