[C#] 목록 추가시 중복된 이름 방지

목록에 항목을 추가할 때 키라던가 이름이 중복되지 않아야 할 경우가 있습니다.

항목을 추가할 때 이름이 같은지를 비교해 같은 경우 추가하지 못하게 하거나, 중복된 이름을 이름(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)이 되는 식입니다.

6개의 좋아요

상세한 설명 감사합니다~~^^

1개의 좋아요