문제

속성 주소 라인 1, addressline2, suburb, state, zipcode가있는 주소 개체가 있습니다. (더 많은 것이 있지만 이것은 예에 충분합니다). 또한 이러한 각 특성은 문자열입니다. 그리고 나는 c# 3.0을 사용하고 있습니다.

나는 그것을 문자열로 표현하고 싶지만, 내가하고있는 것처럼, 나는 모든 if 진술로 인해 높은 순환 복잡성을 가진 방법을 만들고 있음을 발견했습니다 ...

각 속성에 할당 된 문자열이 속성의 이름과 동일하다고 가정하면 (예 : addressLine1 = "jand

"주소 라인 1 주소 라인 2 교외 상태 zipcode".

이제 내가 이것을했던 원래의 방법은 간단한 string.format ()에 의한 것입니다.

String.Format("{0} {1} {2} {3} {4}", address.AddressLine1, 
address.AddressLine2, address.Suburb, address.State, address.ZipCode);

이 필드 중 일부가 비어있을 수 있다는 것을 알 때까지 이것은 모두 훌륭하고 좋습니다. 특히 주소 라인 2. 결과는 추가 불필요한 공간이 있습니다.

이 문제를 해결하기 위해, 내가 생각할 수있는 유일한 솔루션은 문자열을 수동으로 빌드해야했고 널 또는 비어 있지 않은 경우 주소 속성을 문자열에만 추가해야했습니다.

string addressAsString = String.Empty;

if (!String.IsNullOrEmpty(address.AddressLine1))
{
    addressAsString += String.Format("{0}", address.AddressLine1);
}

if(!String.IsNullOrEmpty(address.AddressLine2))
{
    addressAsString += String.Format(" {0}", address.AddressLine2);
}

etc....

내가 생각하지 않는이를 달성 할 수있는 더 우아하고 간결한 방법이 있습니까? 내 솔루션 그냥 느낌 지저분하고 부풀어 오른다 ...하지만 더 좋은 방법을 생각할 수 없다 ...

내가 아는 모든 것에 대해, 이것은 내가하고 싶은 일을 감안할 때 나의 유일한 옵션입니다 ... 그러나 나는 단지 나보다 더 많은 경험을 가진 사람이 더 나은 방법을 알고 있는지 확인하기 위해 이것을 버릴 것이라고 생각했습니다. 더 나은 옵션이 없다면 오 잘하지만 ... 만 있다면, 나는 내가 전에 몰랐던 것을 배우게 될 것입니다.

미리 감사드립니다!

도움이 되었습니까?

해결책

이것은 아마도 가장 효율적인 방법은 아니지만 간결합니다. 원하는 항목을 배열에 넣고 상당한 값없이 배열을 필터링 한 다음 합류 할 수 있습니다.

var items = new[] { line1, line2, suburb, state, ... };
var values = items.Where(s => !string.IsNullOrEmpty(s));
var addr = string.Join(" ", values.ToArray());

아마도 더 효율적이지만 읽기가 다소 어렵다는 것은 값을 StringBuilder, 예를 들어

var items = new[] { line1, line2, suburb, state, ... };
var values = items.Where(s => !string.IsNullOrEmpty(s));
var builder = new StringBuilder(128);
values.Aggregate(builder, (b, s) => b.Append(s).Append(" "));
var addr = builder.ToString(0, builder.Length - 1);

나는 아마도 훨씬 단순하고 유지 관리 가능한 코드이기 때문에 첫 번째 구현과 같은 것에 기대어있을 것입니다. 그리고 성능이 문제라면 두 번째와 같은 것을 고려하십시오 (더 빨리 나오는 경우).

(이것은 C# 3.0이 필요하지만 언어 버전을 언급하지 않으므로 이것이 괜찮다고 가정합니다).

다른 팁

문자열을 합치면 StringBuilder 클래스를 사용하는 것이 좋습니다. 그 이유는 System.String이 불변이기 때문에 문자열로 변경하는 모든 변경은 단순히 새 문자열을 반환합니다.

텍스트로 객체를 표현하려면 tostring () 메소드를 무시하고 구현을 거기에 넣는 것이 좋습니다.

마지막으로, C# 3.5의 LINQ를 사용하면 Greg Beech와 같은 사람들과 함께 참여할 수 있지만 String.join () 사용을 사용하는 대신 :

StringBuilder sb = new StringBuilder();
foreach (var item in values) {
  sb.Append(item);
  sb.Append(" ");
}

도움이 되었기를 바랍니다.

Tostring 메소드를 재정의하는 것이 좋습니다. 사용자 정의 유형을 정의하는 iforMatprovider 구현을 수행합니다.

MSDN을 참조하십시오 http://msdn.microsoft.com/en-us/library/system.iformatprovider.aspx iformatprovider 구현에 대한 정보.

그런 다음 다음과 같은 코드를 작성할 수 있습니다.
address.toString ( "S"); // 짧은 주소
address.toString ( "무엇이든"); // 정의하는 사용자 정의 형식.

확실히 가장 쉬운 방법은 아니지만 가장 깨끗한 IMHO. 이러한 구현의 예는 DateTime 클래스입니다.

건배
금연 건강 증진 협회

첫째, 주소에는 특정 정보가 필요하므로 지퍼 코드가없는 주소를 허용하지 않아야합니다. 또한 각 속성을 빈 문자열로 초기화하거나 각 속성을 생성자에 대한 인수로 요구하여 무효가되지 않도록 할 수 있습니다. 이렇게하면 유효한 데이터를 이미 다루고 있다는 것을 알고 있으므로 iSnullorEmpty 검사가 필요없이 형식의 문자열을 출력 할 수 있습니다.

나는 잠재적으로 여러 개의 빈 필드를 가질 수있는 멀티 라인 연락처 요약을 구축하는 비슷한 문제가있었습니다. 나는 문자열 빌더를 사용하여 문자열에 반복해서 연결하지 않는 것을 제외하고는 당신이 한 것과 거의 같은 일을했습니다.

데이터가 완전히 신뢰할 수없는 경우 해당 논리가 어딘가에 있어야합니다. 해당 논리를 수행하는 다른 읽기 전용 속성 (FormattedAddress와 같은 부르기)을 작성하는 것이 좋습니다. 그렇게하면 코드를 변경할 필요가 없습니다. 어느 시점에서 규칙을 정리하거나 변경합니다.

문자열을 연결하는 것과는 달리 StringBuilder를 사용하는 제안의 경우 +1.

나는 이것이 정말로 오래되었음을 알고 있지만 일반적인 해결책을 감지하고 이런 식으로 내 것을 구현했습니다.

private static string GetFormattedAddress(
    string address1,
    string address2,
    string city,
    string state,
    string zip)
{
    var addressItems =
        new []
        {
            new[] { address1, "\n" },
            new[] { address2, "\n" },
            new[] { city, ", " },
            new[] { state, " " },
            new[] { zip, null }
        };

    string suffix = null;
    var sb = new StringBuilder(128);

    foreach (var item in addressItems)
    {
        if (!string.IsNullOrWhiteSpace(item[0]))
        {
            // Append the last item's suffix
            sb.Append(suffix);

            // Append the address component
            sb.Append(item[0]);

            // Cache the suffix
            suffix = item[1];
        }
    }

    return sb.ToString();
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top