2012-05-22 6 views
1

나는 이것에 대해 궁금해하고 있습니다. 개체을 메서드의 매개 변수로 사용하면 지원하겠습니까? 이 일을하는 이유는 과부하가 될 것입니다. 현재, 많은 다른 데이터 유형을 충족하는 메소드를 만들려고합니다 : string, decimal, DateTime ... 목록이 계속됩니다.개체 유형을 매개 변수로 사용

그것은 비록 지저분한지고, 그래서 나는 일을 생각했다

public void GenericMethod(object val) 
{ 
    if (val is string) 
     // process as string 
    else if (val is decimal) 
     // process as decimal 
    else if (val is DateTime) 
     // do something for dt 
    else 
     // ... 
} 

당신이 이러한 방법에 대해 어떻게 생각하십니까 다음? 불필요한 오버 헤드가 발생합니까? (유형 검사 중) 구현 했습니까? 말해 ...

EDIT : 그래, 그냥 부끄러워, 나는 오버로드에 익숙해. 하지만 10 개 이상의 과부하가 발생하면 조금 성가 시게됩니다 ...

+1

기술적으로는 효과적이지만 확실한 이유가 없으면 좋은 아이디어는 아닙니다. –

+0

궁극적으로 당신의 방법에서 당신이하고있는 일과 당신의 방법이 각 유형마다 얼마나 다른가에 달려 있습니다. 이상적으로는 제네릭을 실제로 사용하고 모두 유사한 경우 범용 매개 변수를 일반화하십시오. 그들이 근본적으로 다르다면 이것은 분명히 좋은 생각이 아닙니다. 당신의 경우에 무엇이 적절한 지 말하기는 불가능합니다. –

답변

7

나는 이것에 대해 궁금해했다. 당신은 당신의 방법에서 매개 변수로 단순히 객체를 사용하는 것을지지하겠습니까?

매우 드뭅니다. 제대로 지원되는 고정 된 유형의 유형이있는 경우 - 그렇지 않으면 예외가 발생합니다. 그런 다음 오버로드를 사용합니다.

유형을 실제로 수락하고 잘 알려진 방식으로 특별히 지원되지 않는 유형을 처리하는 경우 object을 수락해도됩니다. 이것이 바로 LINQ to XML이 곳곳에서하는 일이며 결과는 매우 깨끗한 API입니다. 나는 아주 조심스럽게 그것을 할 것입니다 - 그것은 드물게 좋은 아이디어입니다.

네, 오버 헤드가 있습니다. 나는 대개 결정의 기초가되지는 않을 것입니다 - 오버 헤드는 대부분의 경우 무시할 정도로 작을 것입니다. 가능한 한 깔끔하게 API를 디자인 한 다음 병목 현상을 일으킬 수 있는지 확인하십시오.

9

네, 그게 효과가 있습니다. 그러나 이것을하는 더 좋은 방법이 있습니다.

가장 좋은 방법은 오버로드를 사용하는 것입니다

public void GenericMethod(string val) 
{ 
     // process as string 
} 
public void GenericMethod(decimal val) 
{ 
    // process as decimal 
} 

를 등 당신이 아마 몇 가지 중요한 O.O.을 사용 잊고있어 큰 힌트의 코드에서 is 키워드를 사용할 때마다

원리 : 오버로드, 서브 클래스 등.

오버로드는 실제로 쓰기 만하면 성가신 것이 아닙니다. 기억하지 말라. 오늘은 너 자신을 위해 이것을 코딩하지 말고, 지금부터 코드를 읽고 왜 그렇게했는지, 아니면 세상 어디에서 버그는에서 온다.

"스위치 유형"기술을 피하기위한 또 다른 이유는 .NET 프레임 워크와 일관성을 유지하기위한 것입니다 (따라서 사람의 기대치). Console.Write과 주어진 클래스 내에서 오버라이드되는 다른 다양한 메소드를 따르십시오.

+0

예, 우리는 모두 "왜 그런 짓을했는지"와 "어디에서 버그가 생겨난"상황을 겪었습니다. 나는 다른 사람들이 여러 가지 과부하를 통해 자신의 길을 일해야하는 대신 단순히 한 가지 방법으로 작업하는 것이 더 효과적이라고 생각했습니다. – matt

+0

@matt ... 정말로. 나는 .NET이하는 일에 익숙하다. 타입 당 하나의 과부하가있다. 만약 당신이 그것을 변경하려한다면 나는 꽤 혼란 스러울 것이다. – Crisfole

3

예, 값 유형 검사와 boxing/unboxing 모두에 오버 헤드가 발생합니다. 오버로드를 권장합니다.

숫자로 많은 수학을 수행하지 않는 한 또 다른 가능성은 일반적인 방법으로 만드는 것입니다. 연산자는 연산자를 사용할 수있는 값 유형에 대한 제약이 없기 때문에 제네릭에서는 다소 어렵습니다.

1

귀하의 접근 방식이 적합한 경우가 있습니다. 나는 이전에 그것을 사용했다. 대부분 다른 데이터 유형에 대해 동일한 처리를하는 경우였다.

하지만 과부하가 아닙니다. 오버로드 같은 같은 방법으로 이름을 다른 서명을 정의하는 것입니다 :

public void GenericMethod(string val) 
{ 
    // process as string 
} 

public void GenericMethod(decimal val) 
{ 
    // process as decimal 
} 

public void GenericMethod(DateTime val) 
{ 
    // do something for dt 
} 

// Etc. 

그리고 어떤 경우에 대한

는이 방법이 더 의미가 있습니다.

+0

약한 마음을 가진 사람들이 포도를 빠뜨리지 않고 답을 내려 이유를 설명하는 것처럼 보입니다. –

0

많은 과부하를 구현하는 중 하나는 object에 아무런 문제가 없습니다. 예를 들어 Console.WriteLine 오버로드를 살펴보십시오. http://msdn.microsoft.com/en-us/library/system.console.writeline.aspx 그러나 예를 들어 int가 double과 충돌 할 수 있습니다.

int sum(int i, int j) 
{ 
return i + j; 
} 

double sum(double i, double j) 
{ 
return i + j; 
} 

object sum(object i, object j) 
{ 
    return i.ToString() + j.ToString(); 
} 

============================== 

static void Main() 
{ 
    sum(1, 2); // Error: ambigous call between `int` and `double` versions 
    sum(1.0, 2.0); // calls double version, although 1.0 and 2.0 are objects too 
    sum("Hello", "World"); // object 
} 
3

필요하지 않습니다.

원하는만큼 같은 이름의 메소드를 선언하고 각 메소드에서 각 유형을 인수로 취하십시오. [오버로드라고합니다. 예 : 기본적으로

void Method(decimal d) 
{ 
    //Process Decimal 
} 
void Method(string s) 
{ 
    //Process String 
} 

, 그것은 자신의 방법을 찾을 것입니다 : 당신은 +1 Overloads이 같은 이름이지만 다른 인수 타입]

이 같이 말 1 개 이상 방법이 있다는 것을 의미한다 방법, 옆에 있음을 알 수도 유형에 따라.

관련 문제