2012-07-21 6 views
4

에서 값 유형을 사용하는 방법은 다음과 같은 코드를 가지고 :제네릭

public class Class1 
{ 
    void ValueSpecific(string arg) 
    { 
     // do string stuff 
    } 
    void ValueSpecific(int arg) 
    { 
     // do int stuff 
    } 
    void ValueSpecific(float arg) 
    { 
     // do float stuff 
    } 
    void ValueGeneric(string arg) 
    { 
     // do stuff 
     ValueSpecific(arg); 
     // do more stuff 
    } 
    void ValueGeneric(int arg) 
    { 
     // do stuff 
     ValueSpecific(arg); 
     // do more stuff 
    } 
    void ValueGeneric(float arg) 
    { 
     // do stuff 
     ValueSpecific(arg); 
     // do more stuff 
    } 
    void Main(string s, int i, float f) 
    { 
     ValueGeneric(s); 
     ValueGeneric(i); 
     ValueGeneric(f); 
    } 
} 

이 작동하지만 ValueGeneric의 세 가지 오버로드의 신체의가 동일합니다. 내가 좋아하는 뭔가 보일 것 한 가지 방법으로 그들을 아말감 할 :

void ValueGeneric<T>(T arg) where T: string, float, int 
{ 
    // do stuff 
    ValueSpecific(arg); 
    // do more stuff 
} 

을하지만, 물론, 유효 C#을하지 않습니다.

void ValueGeneric(object arg) 
{ 
    // Do stuff 
    if (arg is int) 
    { 
     ValueSpecific((int)arg); 
    } 
    else if (arg is string) 
    { 
     ValueSpecific((string)arg); 
    } 
    else if (arg is float) 
    { 
     ValueSpecific((float)arg); 
    } 
    else 
    { 
     Debug.Assert(false, "Invalid type) 
    } 
    // Do more stuff 
} 

그러나 이것은 매우 우아 보인다 내가 가지고 올 수있는 최선이다. 나는 어떤 제안을 주셔서 감사합니다. (모든 솔루션에 관심이있는 반면, .NET3.5에서 지원하는 솔루션이 가장 좋을 것입니다.

+0

이 작업을 원한다면 리플렉션을 사용해야합니다. –

+0

확장 방법은 어떨까요? –

+0

@JeffMercado가 맞습니다. 우아하게 보이기 위해서는 Reflection을 사용해야합니다. – pikzen

답변

2

모든 오버로드에서 동일한 작업을 수행 중이라고 가정합니다. , 코드에서 다른 것을 분해하고 매개 변수화하는 일반적인 접근법을 적용 할 수 있습니다. 변경되는 유일한 사항은 전달 된 인수와 해당 인수에서 수행하는 조치입니다. 그들 모두를 전달합니다.

static void ValueGeneric<T>(T arg, Action<T> action) 
{ 
    // do stuff 
    action(arg); 
    // do more stuff 
} 

그런 다음 적절한 조치를 사용하여 일반 메소드를 호출합니다 (ValueSpecific 오버로드 잘 자체적으로 해결됩니다).

ValueGeneric(s, ValueSpecific); 
ValueGeneric(i, ValueSpecific); 
ValueGeneric(f, ValueSpecific); 
+0

나는 그것을 좋아한다. 감사. BTW에는 "Dynamic"(.NET 4에서 작동하는 onoy)를 사용하는 HatSoft의 것을 포함하여 분 전에 다른 답변이 많이있었습니다.하지만 그들은 모두 사라졌습니다. 운좋게도 나는 HatSoft의 솔루션을 얻었습니다. HatSoft, 삭제 했습니까? 아니면 페이지를 검토하는 사람입니까? – Dave

+0

@Dave. 나는 내가 저지를 수있는 해결책이 아니기 때문에 내 것을 삭제했다.다른 사람들도이를 뒤따를 수도 있습니다. "동적"솔루션은 효과가 있지만 런타임 오류 위험을 감수하는 대신 컴파일 타임에 문제를 찾을 수있는 구체적인 방법을 사용하는 것이 좋습니다. –

0

다른 대형 .NET 프로젝트에서 본 특정 오버로드와 일반 오버로드를 모두 포함 할 수 있습니다. 특정 과부하가 존재하지 않는 경우, 그들은 단지 대신 일반 버전 사용합니다 : 당신이 게시 된 코드의 구조에 의해

void ValueGeneric(int i); 
void ValueGeneric(string s); 
void ValueGeneric(float f); 
void ValueGeneric<T>(T t); 

을, 당신이 이전과 이후에 모든 종류의 일을 할 것 같다 ValueSpecific의 내용이므로 ValueGeneric 모든 오버로드가 오버로드간에 코드 중복을 방지하기 위해 처음과 끝에서 호출하는 개인 PreValueGenericPostValueGeneric 메서드를 만들 수 있습니다.

0

각 유형에 확장 방법을 사용해 보았습니까? 이 경우에 대한 대안이 될 수 있습니다.

클래스를 정의하고 해당 메소드를 정의 할 수 있습니다. 마찬가지로 : 다음

namespace ExtensionMethods 
{ 
    public static class Class1 
    { 
     static void ValueSpecific(this string arg) 
     { 
      // do string stuff 
     } 
     static void ValueSpecific(this int arg) 
     { 
      // do int stuff 
     } 
    } 
} 

하고, 당신이 그들을 사용하려면, 단지

Int32 myIntVar = 20; 
myIntVar.ValueSpecific(); 
String myStringVar = "hi", 
myStringVar.ValueSpecific(); 

을 당신은

using ExtensionMethods; 

만 메소드를 선언하고 사용 추가해야합니다.

+1

흥미로운 아이디어이지만, 불행히도 현실 세계에서는 ValueSpecific 메서드가 정적이 아니며 클래스의 비 정적 메서드입니다. 그것은 엄청난 리팩토링으로 끝날 수 있지만 더 불투명하게 끝날 것이라고 생각합니다. – Dave

+0

예, 그들은 정적이지만, 대안으로 게시하는 것이 흥미로운 것이라고 생각합니다. –