문제

우리는 현재 여부를 논의 확장에 있는 방법.순이가 나쁜거나지 않습니다.거나 어떤 상황에서 확장할 수 있는 방법을 소개 하드 버그를 찾기 위해 또는 다른 방법으로 행동하는 예기치 않게 됩니다.

우리가 함께했:

  • 쓰 extension 방법에 대한 유형되지 않는 당신의 통제하에(예를들면장 또는 파일 이름이 시와 GetTotalSize(),etc...),나쁘기 때문에 소유자의 API 수 있는 방법을 소개 숨기는 우리의 확장과가 서로 다를 수 있습니다 경우.예를 들어에 대한 테스트 null extension 방법은 자동으로 번역으로 든 경우 연장 방법은 더 이상 사용하지 않으로 인해 숨어있다.

질문:

  • 다른 위험한 상황이다"숨"우리가 생각하지 않습니까?

편집:

또 다른 매우 위험한 상황입니다.이 있다고 가정 연장 방법:

namespace Example.ExtensionMethods
{
    public static class Extension
    {
        public static int Conflict(this TestMe obj)
        {
            return -1;
        }
    }
}

고 그것을 사용:

namespace Example.ExtensionMethods.Conflict.Test
{
    [TestFixture]
    public class ConflictExtensionTest
    {
        [Test]
        public void ConflictTest()
        {
            TestMe me = new TestMe();
            int result = me.Conflict();
            Assert.That(result, Is.EqualTo(-1));
        }
    }
}

통지는 네임스페이스 어디에 당신이 그것을 사용하는 것입니다.

지금 당신은 당신을 참조 dll 이:

namespace Example.ExtensionMethods.Conflict
{
    public static class ConflictExtension
    {
        public static int Conflict(this TestMe obj)
        {
            return 1;
        }
    }
}

고의 테스트 실패 할 것이다!그것은 컴파일하지 않고 컴파일러에 오류가 있습니다.그 단순히 실패.신 지정하려면"사용은 예입니다.ExtensionMethods.쟁".컴파일러내는 네임스페이스 이름을 찾을 예입니다.ExtensionMethods.충돌이 있습니다.ConflictExtension 기 전에 예입니다.ExtensionMethods.확장하고 사용하는 것입니다 지 않고 불평에 대한 모 extension 방법.오적한 환경에서 즐길 수 있습니다.

도움이 되었습니까?

해결책

약간의 호기심 :

  • 확장 방법이 호출 될 수 있습니다 null 인스턴스; 이것은 혼란 스러울 수 있지만 (때로는 유용합니다)
  • "숨기기"문제는 다른 의도가 있다면 큰
  • 마찬가지로, 2 개의 다른 네임 스페이스에서 동일한 이름의 다른 확장 방법을 얻을 수 있습니다. 당신이 가지고 있다면 하나 두 네임 스페이스 중에서, 이것은 일관되지 않은 행동으로 이어질 수 있습니다 (어느 것에 따라) ...
  • ...하지만 누군가가 추가하면 a 비슷한 (동일한 시그니처) 코드가 사용하는 두 번째 네임 스페이스의 확장 메소드는 컴파일 타임 (모호함)에 중단됩니다.

(편집하다) 물론 "Nullable<T>/new()"폭탄 (여기를 봐)...

다른 팁

나는 동의하지 않습니다. 확장 방법의 요점은 회원을 블랙 박스 클래스에 추가하는 것입니다. 다른 모든 것들과 마찬가지로 함정이있는 것과 마찬가지로, 당신은 이름 지정, 구현에 염두에두고 방법의 펙킹 순서를 이해해야합니다.

우리가 방금 찾은 한 번의 파손 Morelinq 프로젝트 : 일반적인 확장 방법을 작성하는 경우 모든 유형에서 작동하는지 확인하는 것은 불가능합니다. 우리는이 서명에 대한 방법을 가지고 있습니다.

public static IEnumerable<T> Concat<T>(this T head, IEnumerable<T> tail)

다음과 같이 사용할 수 없습니다.

"foo".Concat(new [] { "tail" });

때문에 string.Concat 방법...

C#을 사용하는 한 Ruby on Rails를 거의 사용했습니다. Ruby를 사용하면 새로운 확장 방법과 유사한 작업을 수행 할 수 있습니다. 물론 누군가가 방법을 동일하게 지명 한 경우 잠재적 인 문제가 있지만, 폐쇄 클래스에 방법을 추가 할 수 있다는 장점은 잠재적 인 불만을 훨씬 능가 할 수 있습니다 (아마도 설계가 좋지 않거나 계획이 좋지 않을 것입니다).

확장 방법이 다른 방법 (확장 또는 기타)과 충돌하지 않도록하기 위해 할 수있는 한 가지는 사용하는 것입니다. fxcop 다음과 같은 규칙이 있습니다 중복 확장 방법 서명을 방지합니다.

첫째 모든 믿는 당신의 표현은 조금 잘못된 것입니다.나는 그것을 당신에 대해 이야기하고"유형"과지 않을 수 있습니다.

둘째로,가장 큰 장점의 확장자는 방법이 추가할 수 있는 기능을 입력하지 않을 제어합니다.을 제어하는 경우에는 유형,왜 그냥 수정 유형에 의존하는 대신 extension 방법?

우리는 내 팀의 연장 방법이 너무 유용하여 현실적으로 금지 할 수는 없지만 (주로 은신처 문제로 인해) 약간 조심해야한다는 태도를 취했습니다. 그래서 우리는 모든 확장 방법 이름을 다음과 접두사해야한다고 결정했습니다. X (그래서 우리는 많은 것들이 있습니다 XInit...() 예를 들어 유용한 방식으로 제어를 초기화하는 방법). 이런 식으로 a) 명명 충돌 가능성이 줄어들고 b) 프로그래머는 자신이 클래스 방법이 아닌 확장 방법을 사용하고 있음을 알고 있습니다.

.NET 호출 확장 방법은 제한된 형태입니다. 원숭이 입자 (거기에있는 PHP rant를 무시하십시오).

그것은 당신에게 당신의 토론을위한 자료를 제공해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top