ToString()
To string 은 현재 object 를 string 으로 나타내는 값입니다. 따라서 디버깅 수행을 위해서 꼭 필요한 내용입니다.
만약 Money 이라는 class 가 있을경우 ToString() 을 하면 'Money ' 이라고 찍힐겁니다. 이렇게 찍힌다면 디버깅 목적으로도 부족해보입니다. 따라서 좀더 확장된 내용을 확인하는 방법이 필요합니다.
사용자들을 위해 모든 타입에 적절한 ToString() 메소드를 반드시 제공하는 것이 좋다. 이렇게 타입을 사람이 읽을수 있는 문자열 형태로 표현할 수 있게 되면 어떤 형태인가와 상관없이 좀더 쉽게 객체의 상태를 출력해볼수 있다.
출처 : Effective C# P56
문자열 형식 지정을 더 많이 제어해야 하는 파생 클래스의 경우에는 ToString 메서드에서 현재 스레드의 속성을 사용하도록 IFormattable을 구현해야 합니다.
출처 : msdn.microsoft.com
즉 정교한 내용을 찍기 위해서는 IFormattable 를 사용하여야 하는데 IFormattable는 ...
IFormattable.ToString() 메서드는 사용자의 요구사항을 쉽게 구현할 수 있도록 구성되어 있다. IFormattable.ToString() 메서드는 format 문자열 format 프로바이더를 전달받을수 있다.
format 문자열은 타입을 어떠한 형태로 출력할 것인가를 지정하는데, 그내용은 우리가 임의로 정할수 있다.
format 문자열은 타입을 어떠한 형태로 출력할 것인가를 지정하는데, 그내용은 우리가 임의로 정할수 있다.
출처 : Effective C# p57, 58
IFormattable.ToString 은 두가지 값을 받습니다.
ACE="preserve">string ToString (
string format,
IFormatProvider formatProvider
)우선 첫번째값인 format 부터 어떤 값을 넣어야 하는지 확인해본다면.
어떤 형식을 사용할껀지 정의와도 같습니다 Money 에 amount, denomination 가 있을 경우 format 자리에 "a" 를 넣음면 amount 만 찍히고 "d" 를 넣으면 denomination 만 찍히도록 하는 type 에 가깝습니다.
좋은 예제는 ..
public override String ToString() { return ToString(null, null); }
public String ToString(String format, IFormatProvider fp)
{
// If no format is passed, display like this: (x, y).
if (format == null) return String.Format("({0}, {1})", x, y);
// For "x" formatting, return just the x value as a string
if (format == "x") return x.ToString();
// For "y" formatting, return just the y value as a string
if (format == "y") return y.ToString();
// For any unrecognized format, throw an exception.
throw new FormatException(String.Format("Invalid format string: '{0}'.", format));
}
출처 : msdn.microsoft.com
위에 예제를 보면 x, y 값을 format 형식에따라 찍어내지만 이렇게 끝내는것 보다는 좀더 일반적인 형태를 만드는것이 좋습니다.
Effective C#책을 보면 다음과 같이 제시하고 있습니다.
IFormattable.ToString() 을 어떻게 구현해도 상관없지만 일반적으로 IFormattable interface를 구현할 때 지켜야 하는 몇가지 규칙이 있다. 첫번째로 일반적인 출력형태 "G" .. 생략. 둘째 비어있는 문자열 "" 와 null 전달될 경우 고려, 마지막 규칙은 "G","",null 을 전달했을때 반환되는 문자열은 Object.ToString() 메서드가 반환하는 문자열과 동일해야한다.
출처 : Effective C# p56
"G" 형태가 무언가 하니... 참고해야할 내용은 String.Format 입니다.
String.Format 은 변경할 형식이 있고 그 형식에 대처할 값을 object 로 받습니다.
위 예제에서 (String.Format("Invalid format string: '{0}'.", format)); {0} 자리에 뒤에 있는 format 이라는 값이 대처합니다. 이때 앞에 있는 형식은 3가지로 형태로 조합할수가 있습니다 . 이때 기본 형식인 "G" 가 나옵니다.
- index
형식을 지정할 개체 목록 내 요소를 나타내는 0부터 시작하는 정수입니다. index로 지정된 개체가 Null 참조(Visual Basic의 경우 Nothing)인 경우 형식 항목은 빈 문자열("")로 대체됩니다.
- alignment
형식이 지정된 값이 포함된 영역의 최소 너비를 나타내는 선택적 정수입니다. 형식이 지정된 값의 길이가 alignment보다 작으면 영역의 여백을 공백으로 채웁니다. alignment가 음수이면 형식이 지정된 값은 영역의 왼쪽에 맞춰지고 alignment가 양수이면 형식이 지정된 값은 오른쪽에 맞춰집니다. alignment가 지정되지 않으면 영역의 길이는 형식이 지정된 값의 길이입니다. alignment를 지정하는 경우에는 쉼표가 필요합니다.
- formatString
형식 지정자로 이루어진 선택적 문자열입니다. formatString이 지정되어 있지 않고 해당 인수가
IFormattable 인터페이스를 구현하면 Null 참조(Visual Basic의 경우 Nothing)이
IFormattable.ToString 형식 문자열로 사용됩니다. 그러므로 IFormattable.ToString의 모든 구현에서는 Null 참조(Visual Basic의 경우 Nothing)을 형식 문자열로 사용하고 개체 표현의 기본 형식을 String 개체로 반환해야 합니다. formatString을 지정하는 경우에는 콜론이 필요합니다.
}
출처 : msdn.microsoft.com
즉 {0} 자리에 {0:G} 이런식으로 넣는거와 같습니다. 위에 예제에 첫 if 문에 조건을 바꾸어서
if (format == null || format =="G") return String.Format("({0}, {1})", x, y); 이와같이 해주는것이 좋다는 겁니다.
두번째로 IFormatProvider 는 "GetFormat" 하나만을 제공합니다. msdn 에 정의된 GetFormat 는 다음과 같습니다.
지정된 형식의 형식 지정 서비스를 제공하는 개체를 가져옵니다.
추가 설명 :
. GetFormat은 Type 매개 변수가 ICustoMFormatter 를 구현하는 클래스를 참조하면 자체에 대한 참조를 반환하고, 그렇지 않으면 GetFormat은 Null 참조(Visual Basic의 경우 Nothing)를 반환합니다.
출처 : msdn.microsoft.com
지정된 형식의 형식 지정 서비스를 제공하는 개체를 가져온다...한국말이지만 참 어려운거 같습니다. 하지만 다음 설명을 본다면 이해에 도움이 됩니다 .
특정 타입을 사용하는 사용자가 미처 우리가 예측하지 못한 형태의 출력문자열을 만들고자 할 때 사용할수 있다.
..생략...
우리는 사용자들이 원하는 모든것을 사전에 다 준비할수는 없는 노릇이다. 이를 보완하기 위해서 두번째 인자로 전달받은 IFormatProvider 를 구현한 객체를 이용하여 ICustomFormatter Interface 를 구현한 객체를 찾아내고 그 객체에 문자열 생성을 위임하는 루틴을 구현하였다.
..생략...
우리는 사용자들이 원하는 모든것을 사전에 다 준비할수는 없는 노릇이다. 이를 보완하기 위해서 두번째 인자로 전달받은 IFormatProvider 를 구현한 객체를 이용하여 ICustomFormatter Interface 를 구현한 객체를 찾아내고 그 객체에 문자열 생성을 위임하는 루틴을 구현하였다.
출처 : Effective C# P60




덧글