ToString을 재정의하는 것이 적절한 이유 / 언제? C #을 연구 중이며 ToString아래 예제와 같이

저는 C #을 연구 중이며 ToString아래 예제와 같이 재정의의 요점과 이점이 무엇인지 궁금 합니다.

재정의없이 일반적인 방법을 사용하여 더 간단한 방법으로 수행 할 수 있습니까?

public string GetToStringItemsHeadings
{
    get { return string.Format("{0,-20} {1, -20}", "Office Email", "Private Email"); }
}


public override string ToString()
{
    string strOut = string.Format("{0,-20} {1, -20}", m_work, m_personal);
    return strOut;
}


답변

  • 재정의해야 ToString합니까? 아니.

  • 다른 방법으로 객체의 문자열 표현을 얻을 수 있습니까? 예.

그러나 사용함으로써 ToString당신은 모든 객체에 공통적 인 방법을 사용 하고 있으므로 다른 클래스는이 방법에 대해 알고 있습니다. 예를 들어, .NET 프레임 워크가 객체를 문자열 표현으로 변환하려고 할 때마다는 ToString주요 후보입니다 (더 정교한 서식 옵션을 제공하려는 경우 다른 항목도 있음).

구체적으로

Console.WriteLine(yourObject);

호출 yourObject.ToString()합니다.


답변

.NET 개발 시리즈 의 프레임 워크 디자인 지침 에서 바로 답을 드리려고합니다 .

예외를 던지지 마십시오.ToString

인스턴스와 관련된 고유 한 문자열을 반환하는 것을 고려 하십시오.

출력 ToString이이 유형의 모든 구문 분석 방법에 대해 유효한 입력 이 되도록 고려 하십시오 .

눈에ToString 띄는 부작용이 없는지 확인하십시오 .

DO의 보고서의 재정의를 통해 보안에 민감한 정보를 ToString적절한 권한을 요구 한 후에 만. 권한 요구가 실패하면 보안에 민감한 정보를 제외한 문자열을 반환합니다.

Object.ToString메서드는 일반적인 표시 및 디버깅 목적으로 사용됩니다. 기본 구현은 단순히 객체 유형 이름을 제공합니다. 기본 구현은 그다지 유용하지 않으며 메서드를 재정의하는 것이 좋습니다.

DO의 재정 ToString재미있는 사람이 읽을 수있는 문자열이 반환 할 수 있습니다 때마다. 기본 구현은 그다지 유용하지 않으며 사용자 정의 구현은 거의 항상 더 많은 가치를 제공 할 수 있습니다.

DO는 고유하지만 읽을 수있는 ID를 통해 친숙한 이름을 선호합니다.

Chris Sells ToString가 종종 사용자 인터페이스에 위험한 지침에서 설명하므로 언급 할 가치가 있습니다. 일반적으로 내 경험 법칙은 정보를 UI에 바인딩하는 데 사용되는 속성을 노출 ToString하고 개발자에게 진단 정보를 표시하기위한 재정의를 남겨 두는 것입니다. 당신의 타입을 꾸밀 수도 있습니다 DebuggerDisplayAttribute.

DO는 반환 된 문자열을 유지하려고 ToString짧은. 디버거는 ToString개발자에게 표시 할 개체의 텍스트 표현을 가져 오는 데 사용 합니다. 문자열이 디버거가 표시 할 수있는 것보다 길면 디버깅 환경이 방해를받습니다.

문화권 종속 정보를 반환 할 때 현재 스레드 문화권을 기반으로하는 DO 문자열 형식 지정.

DO는 과부하 제공 ToString(string format), 또는 구현 IFormattable에서 문자열을 반환하는 경우, ToString문화를 구분하거나 문자열을 포맷하는 다양한 방법이 있습니다. 예를 들어, DateTime오버로드를 제공하고 IFormattable.

빈 문자열 또는 null을 반환 하지 마십시오.ToString

이 지침에 따라 맹세합니다. 그렇게해야합니다. .NET에 대한이 가이드 라인만으로 내 코드가 어떻게 개선되었는지 말할 수 없습니다 ToString. 같은 일이 같은 것들에 간다 IEquatable(Of T)하고 IComparable(Of T). 이러한 것들은 여러분의 코드를 매우 기능적으로 만들며, 코드를 구현하는 데 추가 시간을 투자 한 것을 후회하지 않을 것입니다.

개인적으로 저는 사용자 인터페이스에 대해 ToString 많이 사용하지 않았고 , 항상 어떤 종류의 속성이나 메서드를 노출 해 왔습니다. 대부분의 경우 ToString디버깅 및 개발자 목적으로 사용해야 합니다. 중요한 진단 정보를 표시하는 데 사용합니다.


답변

재정의 ToString()하면 사람이 읽을 수있는 유용한 클래스의 문자열 표현을 제공 할 수 있습니다.

이는 출력이 클래스에 대한 유용한 정보를 나타낼 수 있음을 의미합니다. 예를 들어, Person 클래스가 있다면 ToString()그 사람의 ID, 이름, 성 등을 출력 하도록 선택할 수 있습니다 . 이것은 디버깅 또는 로깅시 매우 유용합니다.

귀하의 예제와 관련하여-이 클래스가 무엇인지 모르고 재정의가 유용한 지 여부를 말하기는 어렵지만 구현 자체는 괜찮습니다.


답변

항상 적절하지만 표시하려는 의도를 신중하게 고려하십시오.

더 나은 질문은 다음과 같이 묻는 것입니다.

왜 ToString ()을 재정의합니까?

ToString ()은 객체의 상태에 대한 창입니다. 상태 를 요구 사항으로 강조 합니다. Java / C #과 같은 강력한 OOP 언어는 클래스의 모든 것을 캡슐화하여 OOP 모델을 남용합니다. 강력한 OOP 모델을 따르지 않는 언어로 코딩하고 있다고 상상해보십시오. 클래스를 사용할 것인지 함수를 사용할 것인지 고려하십시오. 이를 함수 (예 : 동사, 액션)로 사용하고 내부 상태가 입력 / 출력 사이에 일시적으로 만 유지된다면 ToString ()은 값을 추가하지 않습니다.

다른 사람들이 언급했듯이 디버거 나 다른 시스템에서 사용할 수 있으므로 ToString ()으로 출력하는 내용 을 고려 하는 것이 중요 합니다.

ToString 메서드를 개체의 –help 매개 변수로 상상하고 싶습니다. 짧고, 읽기 쉽고, 명확하고, 표시하기 쉬워야합니다. 이 객체가 무엇인지 표시해야 입니다 그렇지 않은 것을 않습니다 . 모든 것을 염두에두고 고려해 봅시다 …

사용 사례-TCP 패킷 구문 분석 :

애플리케이션 수준 전용 네트워크 캡처가 아니라 pcap 캡처와 같은 더 많은 기능이있는 것입니다.

TCP 레이어에 대해서만 ToString ()을 오버로드하여 콘솔에 데이터를 인쇄 할 수 있습니다. 무엇이 포함됩니까? 미쳐서 모든 TCP 세부 정보를 구문 분석 할 수 있습니다 (즉, TCP는 복잡합니다) …

다음을 포함합니다.

  • 소스 포트
  • 목적지 포트
  • 시퀀스 번호
  • 승인 번호
  • 데이터 오프셋
  • 플래그
  • 창 오프셋
  • 체크섬
  • 긴급 포인터
  • 옵션 (I은 아니에요 심지어 거기에 갈)

하지만 100 개의 패킷에 대해 TCP.ToString ()을 호출한다면 그 모든 정크를 받고 싶습니까? 물론 정보 과부하가 될 것입니다. 쉽고 분명한 선택도 가장 현명한 선택입니다 …

사람들이보기를 기대하는 것을 노출 :

  • 소스 포트
  • 목적지 포트

나는 인간이 파싱하기 쉬운 합리적인 출력을 선호하지만 YMMV .

TCP:[destination:000, source:000]

복잡한 것은 없습니다. 출력은 기계가 파싱하는 것이 아닙니다 (즉, 사람들이 코드를 남용하지 않는 한). 의도 된 목적은 사람이 쉽게 읽을 수 있도록하는 것입니다.

하지만 이전에 얘기했던 나머지 모든 정보는 어떻습니까? 그렇게 유용하지 않습니까? 그것에 대해 설명하겠습니다.하지만 먼저 …


ToString () 역사상 가장 가치 있고 잘 사용되지 않는 메서드 중 하나

두 가지 이유가 있습니다.

  1. 사람들은 ToString ()이 무엇인지 이해하지 못합니다.
  2. 기본 ‘Object’클래스에 똑같이 중요한 다른 문자열 메서드가 없습니다.

이유 1-ToString ()의 유용성을 남용하지 마십시오.

많은 사람들이 ToString ()을 사용하여 객체의 간단한 문자열 표현을 가져옵니다. C # 설명서에는 다음과 같은 내용도 있습니다.

ToString은 .NET Framework의 주요 서식 지정 방법입니다. 디스플레이에 적합하도록 객체를 문자열 표현으로 변환합니다.

추가 처리가 아닌 표시 . 즉, 위의 TCP 패킷의 멋진 문자열 표현을 가져와 정규식 :: cringe ::를 사용하여 소스 포트를 가져옵니다.

작업을 수행 하는 올바른 방법은 SourcePort 속성에서 직접 ToString ()을 호출하는 것입니다 (BTW는 ushort이므로 ToString ()이 이미 사용 가능해야 함).

머신 파싱을 위해 복잡한 객체의 상태를 패키징하기 위해 더 강력한 것이 필요하다면 구조화 된 직렬화 전략을 사용하는 것이 좋습니다.

다행히도 이러한 전략은 매우 일반적입니다.

  • ISerializable (C #)
  • Pickle (Python)
  • JSON (Javascript 또는이를 구현하는 모든 언어)
  • 비누
  • 기타…

참고 : PHP를 사용하지 않는 한 herp-derp에는 :: snicker ::에 대한 함수가 있습니다.

이유 2-ToString ()이 충분하지 않습니다.

나는 아직 이것을 핵심으로 구현하는 언어를 보지 못했지만이 접근 방식의 변형을보고 사용했습니다.

그중 일부는 다음과 같습니다.

  • ToVerboseString ()
  • ToString (verbose = true)

기본적으로, TCP 패킷의 상태 너무 복잡해서 사람이 쉽게 읽을 수 있도록 설명 해야 합니다. TCP에 대해 말하는 ‘죽은 말을 이길’을 피하기 위해 ToString () 및 ToVerboseString ()이 제대로 활용되지 않는다고 생각하는 # 1 사례에서 ‘손가락을 가리 킵니다’.

사용 사례-어레이 :

주로 한 언어를 사용하는 경우 해당 언어의 접근 방식에 익숙 할 것입니다. 저와 같이 다른 언어로 넘어가는 사람들에게는 다양한 접근 방식이 짜증날 수 있습니다.

즉, 이것이 나를 짜증나게 한 횟수는 모든 힌두교 신의 모든 손가락을 합친 것보다 큽니다.

있습니다 다양한 언어가 일반적인 사용의 경우 해킹을 하고 오른쪽으로 . 일부는 바퀴의 재창조가 필요하고, 일부는 얕은 덤프를, 다른 일부는 깊은 덤프를 수행하며, 어느 것도 내가 원하는 방식으로 작동하지 않습니다.

내가 요청한 것은 매우 간단한 접근 방식입니다.

print(array.ToString());

출력 : ‘Array [x]’또는 ‘Array [x] [y]’

여기서 x는 첫 번째 차원의 항목 수이고 y는 두 번째 차원의 항목 수이거나 두 번째 차원이 들쭉날쭉하다는 것을 나타내는 값입니다 (최소 / 최대 범위는?).

과:

print(array.ToVerboseString());

예쁜 것을 고맙게 생각하기 때문에 전체를 예쁜 글씨로 출력합니다.

바라건대, 이것은 오랫동안 나를 짜증나게 한 주제에 대해 약간의 빛을 비추어줍니다. 최소한 나는 PHPers 가이 답변을 반대 투표하기 위해 약간의 트롤 미끼를 뿌렸습니다.


답변

정말 좋은 습관에 관한 것입니다.

ToString()일반적으로 사람이 소비하기 위해 객체의 문자열 표현을 반환하기 위해 여러 곳에서 사용됩니다. 동일한 문자열 객체를 재수하는 데 사용할 수있는 자주 (생각 int또는 DateTime예를 들어)하지만, 단순히 카운트를 표시하는 유용한 캐릭터 라인 표현이있을 수 있습니다 항상 예를 들어 주어진 (나무 아니지만 분명 당신은 사용할 수 없습니다 그것을 재건하는 것).

특히 디버거는 이것을 사용하여 조사 식 창, 즉각적인 창 등에 변수를 표시하므로 ToString실제로 디버깅에 매우 유용합니다.

일반적으로 이러한 유형에는 종종 문자열도 반환하는 명시 적 멤버가 있습니다. 예를 들어 위도 / 경도 쌍에는 예를 들어 ToDecimalDegrees반환 되는 위도 / 경도 쌍이있을 수 "-10, 50"있지만 ToDegreesMinutesSeconds위도 / 경도 쌍에 대한 또 다른 형식이므로을 가질 수도 있습니다 . 그런 다음 동일한 유형이ToString 디버깅과 같은 항목 또는 잠재적으로 웹 페이지 렌더링과 같은 항목에 ‘기본값’을 제공하기 위해 해당 중 하나로 (예 : @Razor 의 구문은 ToString()문자열이 아닌 표현식 의 결과를 출력 스트림).


답변

object.ToString()객체를 문자열 표현으로 변환합니다. 사용자 ToString()가 생성 한 클래스를 호출 할 때 반환되는 내용을 변경하려면 ToString()해당 클래스에서 재정의해야합니다 .


답변

가장 유용한 정보가 이미 제공되었다고 생각하지만 2 센트를 추가하겠습니다.

  • ToString()재정의를 의미합니다. 기본 구현은 때때로 유용 할 수 있지만 (특히 많은 객체로 작업 할 때) 대부분의 경우 충분하지 않은 유형 이름을 반환합니다.

  • 디버깅 목적으로 DebuggerDisplayAttribute. 여기에서 자세한 내용을 읽을 수 있습니다 .

  • 원칙적으로 POCO에서는 항상 ToString(). POCO는 데이터의 구조화 된 표현이며 일반적으로 문자열이 될 수 있습니다.

  • 개체의 텍스트 표현이되도록 ToString을 디자인합니다. 주요 필드 및 데이터, 컬렉션에있는 항목 수에 대한 설명 등이 될 수 있습니다.

  • 항상 해당 문자열을 한 줄에 맞추고 필수 정보 만 가지고 있어야합니다. Person이름, 주소, 번호 등 속성 이있는 클래스 가있는 경우 기본 데이터 만 반환합니다 (이름 일부 ID 번호).

  • 의 좋은 구현을 재정의하지 않도록주의하십시오 ToString(). 일부 프레임 워크 클래스는 이미 ToString(). 기본 구현을 재정의하는 것은 나쁜 일입니다. 사람들은 특정 결과를 기대하고 ToString()또 다른 결과를 얻습니다.

사용하는 것을 정말로 두려워하지 마십시오 ToString(). 내가 조심해야 할 유일한 것은 민감한 정보를 반환하는 것입니다. 그 외에는 위험이 최소화됩니다. 물론 일부가 지적했듯이 다른 클래스는 정보를 얻을 때마다 ToString을 사용합니다. 그러나 도대체 언제 유형 이름을 반환하는 것이 실제 정보를 얻는 것보다 더 나은 것으로 간주됩니까?