2009-10-11 8 views
5

오버로드 된 메서드에서 다른 반환 유형을 반환하는 모범 사례가 있습니까? 예를 들어 DAL에 Load 메서드가있는 경우 단일 항목이나 여러 항목을로드하려고합니다. 내가 접근 방법 사용할 수 있다는 것을 알고오버로드 된 메서드에서 다른 반환 유형을 사용해야합니까?

로드 하나의 객체

MyBusinessObject LoadOne(int id) 
{ 
} 

로드 여러 개체

MyBusinessObject[] LoadMany(params int[] ids) 
{ 
} 

지금 뭔가 내가 아는을 I 할 하나의 방법을 과부하하는 것입니다 다른 반환 유형이 있습니다. 그래서 같이 :

MyBusinessObject Load(int id) 
{ 
} 

그리고

MyBusinessObject[] Load(params int[] ids) 
{ 
} 

거기 내가이 일을 중지 아무것도 없다, 그리고는 API 관점에서 깔끔한 일을 계속 보이지만

, 이것은 좋은 생각처럼 보인다? 나는 어젯밤 그것을 가로 질러 왔고, 나 부분은 오버로드 된 메소드에 대해 일치하는 리턴 타입을 원했기 때문에 이것을하지 말아야한다고 생각한다.

Load (int id) 메서드는 하나의 항목 만 보유하는 컬렉션을 반환 할 수도 있습니다. 이것은 하나의 항목이 반환 될 것으로 예상되는 경우 해당 항목을 반환해야하며 단일 항목을 포함하는 목록을 반환하면 안된다는 점에서 이는 최소한의 놀라움의 원칙을 위반하는 것으로 보입니다. 그래서 여기

는 이러한 아이디어를 둘러싼 내 충돌하는 생각입니다

  • 오버로드 방법은 모두 같은 유형을 반환해야합니다.
  • 메서드가 동일한 작업을 수행하는 경우 동일한 메서드 이름에 여러 가지 다른 이름을 지정하지 마십시오. API 사용자의 관점에서 볼 때 더 간단하게 처리 할 수 ​​있기 때문에 기본적으로 같은 일을하지만 매개 변수가 다른 여러 가지 방법을 통해 트래킹 할 필요가 없습니다.
  • 가장 확실한 유형의 메소드를 반환합니다. 즉, 사용자가 아이템 컬렉션을 기대할 가능성이있는 경우 단일 아이템을 기대할 가능성이있는 경우 아이템 컬렉션을 반환하고 단일 아이템을 반환합니다.

그래서 두 번째 생각이 처음 것보다 중요하지만 동시에 첫 번째 생각은 프로그램 방식의 모범 사례처럼 보입니다.

이 연습을 둘러싼 모범 사례가 있습니까? 주제에 대한 다른 사람들의 생각을 듣고 싶습니다.

+0

어쨌든 배열 대신에'IEnumerable '를 반환하는 것을 고려하십시오. 에릭 리 퍼트 (Eric Lippert)는 이에 대한 훌륭한 블로그 글을 가지고 있습니다. –

+0

배열을 반환하면 시나리오가 강조 표시됩니다. 내 실제 코드에서 IEnumerable을 반환합니다. – BenAlabaster

+0

좋습니다. 네가 알고있는 한. –

답변

8

나는 이름의 API 명시 적으로 사용 복수를하기 위해 유혹 될 수 있습니다

Customer LoadCustomer(int id) {...} 
Customer[] LoadCustomers(params int[] id) {...} 

는 사실, params 여기에 거의 유용합니다 - 당신은 일반적으로 컴파일 타임에 ID를 모른다.

+0

params와 관련하여, 나는 당신의 요점을 이해하지만 실제 코드 경로보다는 개념을 강조하고있었습니다. 나는 실생활 시나리오에서 하나의 항목보다는 잠재적 인 항목 목록을 반환하는 필터링 정보를 전달할 것이라고 생각합니다. 나는 복수형이라는 생각을 좋아한다. 그것은 여러 가지 방법을 인텔리 센스로 유지할 것이다. – BenAlabaster

0

내 개인적인 생각은 후자의 방법이 API 사용자 관점에서 더 이해하기 쉽다는 것입니다.

3

기존 API를 살펴볼 수 있습니다. LINQ를 예로 들어 봅시다. 많은 엔터티를 반환하는 "Select"메서드와 하나의 엔터티 만 반환하는 "Single"메서드가 있습니다. 기존 API의 대부분은 오버로드 된 API가 아닌 두 가지 메소드를 가지고 있으며 논리적이고 읽기 쉽다고 생각합니다.

+0

그러나 또한 API가 동일한 작업을 수행하는 많은 메소드로 흩어져 있다는 것을 의미합니다. – BenAlabaster

+0

그 외에도 다른 사람들의 API를 예로 들자면 이런 식으로 설계 한 생각 프로세스를 이해하는 데 도움이되지 않습니다. 오히려 생각이없는 API가없는 API보다 생각 프로세스가 6 가지 다른 예를 * 볼 수 있습니다. 이렇게하면 다른 사람의 모범을 따라가는 것보다는 맹목적으로 정보통에 의한 결정을 내릴 수 있습니다. – BenAlabaster

+0

나는 맹목적으로 추종자가 아니다. =) 나는 내 의견을 쓰고 있으며, 선도적 인 기술은 최소한 내 관심을 끌만한 가치가있다. 그런데 하나의 엔티티를 가져오고 여러 엔티티를 가져 오는 것은 같은 것이 아닙니다. – Restuta

2

나는 "오버로드가 같은 유형을 반환해야합니다"라는 "이 생각을 암시하는 생각" 목록의 첫 번째 요점을 따르는 경향이 있습니다.

하지만 "LoadMany"를 다른 시나리오로 오버로드 할 수 있습니다.

public Customer Load(int id) 
{ 
    // return just one customer 
} 

public List<Customer> LoadMany() 
{ 
    // return every single customer 
} 

public List<Customer> LoadMany(int statusFilter) 
{ 
    // return a filtered list of customers 
} 

public List<Customer> LoadMany(DateTime InitialContactFrom) 
{ 
    // return a filtered list of customers 
} 

public List<Customer> LoadMany(DateTime InitialContactFrom, DateTime InitialContactBefore) 
{ 
    // return a filtered list of customers 
} 

... 분명히 추가 할 수 있지만 결국에는 LoadMany가 목록을 반환하고 Load는 하나의 엔터티를 반환합니다.

3

아마도 예외가있을 수 있지만, 다른 유형을 반환해야하는 정말 좋은 이유가 없다면 함수와 오버로드가 같은 유형을 반환해야 다른 개발자를 미치게 만들 수 없습니다. 예를 들어

: 그들은 나에게 동일한 유형으로 VAR를 해결해야처럼

var a = MyFunc("Some text"); 

var a = MyFunc(1); 

모두 찾습니다. 모든 오버로드가 동일한 유형을 반환하는 것을 벗어나기 전에 다른 유형을 반환하는 매우 확실한 이유가 있음을 확인했습니다.

+0

공정한 점은 가능한 모든 다른 코드를 참조하여 가능한 한 모든 라인을 가능한 한 이해하도록하는 나의 신조를 실제로 위반하는 var 관점을 고려하지 않았습니다. – BenAlabaster

관련 문제