2017-04-18 2 views
0

문제를 재검토 한 후 알립니다. @Dogu Arslan이 WriteData 메서드를 사용한 정확한 예제를위한 최상의 솔루션을 제안했지만 질문 제목의 문제는 실제로 @InBetween과 @Fabio에 의해 해결되었습니다. I. e. WriteData 메서드의 정확한 예를 보려면 WriteData 메서드에서 변환 논리를 이동하는 것이 더 좋지만 관련이없는 형식의 논리를 추상화하려면 제안 된 오버로드를 사용하는 것이 좋습니다. 그래서 세 가지 대답이 모두 도움이됩니다.관련없는 유형에서 연산을 추상화하는 방법은 무엇입니까?

나는 이미 다음과 유사한 질문 - 1, 2 및 기타를 읽었지만 내 경우에는 적절한 해결책이 제공되지 않았습니다.

제 경우 : 다음과 같은 간단한 방법이 있습니다. 중요한 부분은 주석과 "소스"매개 변수가있는 행입니다. 나머지 부분은 그다지 중요하지 않으며 질문 제목의 "조작"이 있음을 보여주는 역할 만합니다.

void WriteData(
    int count, 
    int currentIndex, 
    List<byte> source, 
    StreamWriter sw, 
    string fileName) 
{ 
    var countToWrite = count - currentIndex; 

    if (countToWrite == 0) 
     return; 

    if (sw == null) 
     sw = new StreamWriter(GetFullPath(fileName)); 

    //---------- Source's elements must be converted to string. 
    var dataToWrite = 
     source.GetRange(currentIndex, countToWrite) 
     .Select(x => Convert.ToString(x)); 

    StringBuilder sb = new StringBuilder(); 

    foreach (var item in dataToWrite) 
     sb.AppendLine(item); 

    sw.Write(sb.ToString()); 
} 

지금은 "원본"매개 변수를 바이트, 복식 또는 문자열 목록으로 지정하고 싶습니다. "source"에있는 목록의 유형 중 하나만 변경 한 WriteData 메서드를 3 부 작성 했습니까? 아니면 더 나은 방법이 있습니까?

유형 제한을 시도했지만 제한 할 유형은 무엇입니까?

내 형식 목록 (byte, double, string)에 없으면 형식을 검사하고 예외를 throw하려고했습니다. 그러나 예외는 런타임에만 작동하며 컴파일 타임에 작동하도록하고 싶습니다.

당분간은 일시적인 해결책으로 런타임 유형 검사와 함께 스스로를 제한해야하지만 앞에서 언급했듯이 관점에서는 적합하지 않습니다.

+0

일반화 할 수 있으며 프로그래밍 방식으로 유형이 지정되었는지/ –

답변

1

한 가지가 다른 클래스의 altogether.ie에 문자열 변환 책임을 제거하는 것입니다 :

+0

나는 당신에 동의합니다. InBetween과 Fabio가 좋은 솔루션을 제안하더라도 가장 좋은 방법은 WriteData 메서드에서 변환 논리를 이동하는 것입니다. – Alex34758

3
왜 "가리는"하나 과부하 방법을 사용하지

실제 솔루션

당신이 유형을 확인하고 잘못된 유형이 주어 졌을 때 개인 방법을 만들기에서 당신은 "보호"할 경우에, 예외를 던질 수있는 개인 방법에서
public void WriteData(List<byte> source) { WriteData<byte>(source); } 
public void WriteData(List<double> source) { WriteData<double>(source); } 
public void WriteData(List<string> source) { WriteData<string>(source); } 

private void WriteData<T>(List<T> source) 
{ 
    // Your actual implementation 
} 

공중에 의해 "실수". 당신이 할 수

public void WriteData(, , List<string> source, ,) { WriteData<string>(...); } 
public void WriteData(, , List<byte> source, ,) { WriteData<byte>(...); } 
public void WriteData(, , List<double> source, ,) { WriteData<double>(...); } 

private void WriteData<T>(, , List<T> source, ,) 
{ 
    Debug.Assert(typeof(T).Equals(typeof(string)) || 
       typeof(T).Equals(typeof(byte)) || 
       typeof(T).Equals(typeof(double))); 
    ... 
} 
+0

확인하십시오. 예외 예외는 런타임과 관련이 있지만 컴파일 타임 오류 또는 경고를 원합니다. – Alex34758

+1

@ Alex34758, 던져 예외는 단지 "보호"의 한층 더했습니다.명시 적으로 선언 된 유형의 공용 오버로드가 컴파일 시간 검사를 제공합니다 – Fabio

+0

내 정확한 질문에 대한 해결책이 좋지만 @DoguArslan과 관련하여 문제를 다시 생각해 봐야하며 WriteData 메소드에서 변환 논리를 제거하는 것이 더 좋습니다 (WriteData 메서드를 호출하기 전에 Convert 클래스로 "source"를 변환 한 다음 결과를 "source"매개 변수로 전달하여 어떤 유형이 List 이 될지) 문제가 제거됩니다. 올바른 아키텍처가 핵심입니다. – Alex34758

2

가장 좋은 방법은 공개적으로 개인 일반적인 방법으로 구현을 위임 한 후 필요에 과부하를 노출하는 것입니다. 이 다양한 입력 유형을 사용하여 문자열로 변환하고 문자열을 반환하는 메서드를 제공하는 오버로드 된 생성자를 사용하는 StringConverter 클래스입니다. 그렇게하면 나중에 지원하는 유형을 확장해도 여기 예제를 변경하지 않아도됩니다.이 모든 것은 문자열 변환기 클래스 뒤에 투명하게 적용됩니다. 문자열 변환기 클래스가 생성자를 통해 입력을 받아들이므로 검사도 컴파일 시간이됩니다. 예, WriteData 메소드를 호출 할 때마다 새 StringConverter 객체를 인스턴스화해야하지만 C#은 쉘프에서 요청하는 레벨에 유형 제약 조건을 제공하지 않습니다.

+0

오, 당신은 @ Fabio처럼 해. 그러나 Public WriteData 메서드의 List 요소에 대한 명시 적 형식이 제네릭 형식 T를 이미 제한한다면 Debug.Assert를 사용해야하는 이유는 무엇입니까? Debug.Assert는 절대로 "거짓"상태가 아닌 것 같습니다. – Alex34758

+2

@ Alex34758 따라서 'Debug.Assert'는 예외이며'throw '가 아닙니다. 아무도 * 외부 * 클래스가 잘못된 유형 (리플렉션 제외)으로 전화를 걸지 만 클래스 내부의 잘못된 호출을 중지하는 것은 없습니다. 그 주장은 안전망으로 존재합니다. – InBetween

+0

귀하의 솔루션은 제 질문과 관련하여 좋지만, @DoguArslan과 관련하여 문제를 다시 생각해보아야하며, WriteData 메소드에서 변환 논리를 제거하는 것이 더 낫습니다 (전화하기 전에 "source"를 Convert 클래스로 변환합니다) WriteData 메서드를 호출 한 다음 결과를 "source"매개 변수로 전달하면 어떤 형식인지 List ) 문제가 제거됩니다. 올바른 아키텍처가 핵심입니다. – Alex34758

관련 문제