2016-10-19 2 views
2

내 확장 방법 해상도에서 예기치 않은 동작이 나타나는 이유를 파악하려고합니다. 나는 Eric Lippert's Closer is Better 기사를 읽었으며 나는 여전히 혼란 스럽다.올바른 확장 메서드 확인 방법

먼저 호출 사이트 : 두 개의 서로 다른 어셈블리에, 나는 두 개의 서로 다른 네임 스페이스에 IOrganziationService에 확장 메서드 오버로드를 정의

// Assembly: Microsoft.Xrm.Sdk 
void Delete(string entityName, Guid id); 

:

// Assembly: DLaB.Xrm.2016.Tests 
using DLaB.Xrm.Entities; 
using DLaB.Xrm.Test; 
using Microsoft.Xrm.Sdk; 

namespace DLaB.Xrm.Tests 

    public class TrialClass{ 
    { 
     public void Delete(){ 
      IOrganziationService service = GetService(); 
      Id<Contact> id = GetId(); 
      service.Delete(id); // Call Site in Question 
     } 
    } 
} 

IOrganizationService이 서명으로 삭제 방법을 정의 :

//Assembly: DLaB.Xrm.2016 
//Namespace DLaB.Xrm 
public static void Delete(this IOrganizationService service, Entity entity) { ... } 
public static void Delete(this IOrganizationService service, EntityReference entity) { ... } 


//Assembly: DLaB.Xrm.Test.2016 
//Namespace DLaB.Xrm.Test 
public static void Delete(this IOrganizationService service, Id id) { ... } 
public static void Delete<T>(this IOrganizationService service, Id<T> entity) where T : Entity { ... } 

나는 또한 가지고있다. 이드의 클래스에 대한 정의 암시 사업자 있다는 Entity로 변환 또는 내가 정의한 내 암시 사업자에서 이해 EntityReference

The Call Site service.Delete(id) shows a compiler error: Error CS0121 The call is ambiguous between the following methods or properties: 'Extensions.Delete(IOrganizationService, Entity)' and 'Extensions.Delete(IOrganizationService, EntityReference)'

. 필자가 이해하지 못하는 것은 DLaB.Xrm 네임 스페이스가 DLaB.Xrm.Test 네임 스페이스보다 더 가까운 이유입니다. 사용 지시문을 사용하지 않아도됩니다.

답변

1

에릭의 블로그에 정의 친밀감의 6 규칙이 있습니다

  1. 첫번째 파생 클래스에서 선언 된 메소드는 우선 기본 클래스에 선언하는 방법보다 가까운이.
  2. 중첩 클래스의 메서드가 포함 된 클래스의 메서드보다 비슷합니다.
  3. 수신 유형의 모든 방법은 모든 확장 방법보다 가깝습니다.
  4. 중첩 된 네임 스페이스의 클래스에있는 확장 메서드가 외부 네임 스페이스의 클래스에있는 확장 메서드보다 가깝습니다.
  5. 현재 네임 스페이스의 클래스에있는 확장 메서드가 using 지시문에서 언급 한 네임 스페이스의 클래스에있는 확장 메서드보다 가깝습니다.
  6. 지시문이 중첩 네임 스페이스에있는 경우 using 지시문에 언급 된 네임 스페이스의 클래스에있는 확장 메서드가 해당 지시문이있는 중첩 된 네임 스페이스에있는 using 지시문에 언급 된 네임 스페이스의 클래스에있는 확장 메서드보다 가까운 경우 외부 네임 스페이스.

첫 번째 3은 인터페이스에 적용 가능한 방법이 없으므로 적용되지 않습니다. 네 번째가 열쇠입니다. DLaB.Xrm은 다른 어셈블리에도 있지만 중첩 된 네임 스페이스에 있습니다. 다른 클래스에서 액세스 할 수 있으려면 확장 메서드의 using 지시문을 나열해야한다고 잘못 판단했습니다. 중첩 된 네임 스페이스의 확장 메서드가 자동으로 사용 가능하다는 것을 알게되었습니다.

namespace DLaB.Xrm.Tests에서 namespace NotNested.DLaB.Xrm.Tests으로 변경하면 모든 친숙한 규칙이 제거되고 모호한 호출은 일반적인 서명 과부하 해결 규칙에 의해 해결됩니다. 내가 사용한 실제 수정 사항은 단지 삭제 호출을 일반화하여 충돌로부터 두 개의 암시 적 변환 과부하를 제거하고 호출을 원하는 방식으로 해결할 수있게하는 것입니다.