2009-09-18 5 views
0

개체가 Email이고 List<Attachment> 속성에있는 첨부 파일의 수를 확인하려고 시도하고 있습니다.LINQ의 유효성 검사를 위해 Add 메서드를 오버로드하는 중

트릭은 우리가 WCF 서비스에서 Send() 메서드를 사용한다는 것입니다. 서버 측의 유효성을 검사하기는 쉽지만 클라이언트 측에서 먼저 유효성을 검사하려고합니다.

서비스를 사용하기 위해 다른 사람들이 사용하기로되어있는 라이브러리를 생성했습니다.이 라이브러리는 모든 개체와 사용 가능한 방법을 포함하는 프록시를 갖습니다. 어떤 추가 할 때 컬렉션을 검사 할 수 있도록 일부 사용자 지정 코드를 사용하여 GenericList에 Add() 메서드를 오버로드 할 수 있어야한다고 생각하고 지정된 최대 값을 초과하면 예외가 throw됩니다.

public partial class List<Attachment> 
{ 
    public void Add(Attachment item) 
    { 
     base.Add(item); 
     if (this.Count() > maxAttachments) 
     { 
      throw new Exception("fail") 
     } 
    } 
} 

이것은 작동하지 않습니다. 클래스 base.Add()를 사용할 수없고 지정된 유형의 부분 클래스를 정의 할 수 없습니다.

일부 사용자 지정 코드를 포함 할 수 있도록 Add 메서드의 오버로드를 어떻게 만듭니 까?

답변

2

Email 클래스를 소유하고있는 경우 최상의 방법은 목록 구성원의 기본 유형을 목록의 특수 구현으로 변경하는 것입니다.

public class Email 
{ 
    const int MaxAttachments = /* ... */; 

    public Email(/* ... */) 
    { 
     this.Attachments = new FixedSizeList<Attachment>(MaxAttachments); 
    } 

    // ... 

    public IList<Attachment> Attachments 
    { 
     get; 
     private set; 
    } 
} 

class FixedSizeList<T> : IList<T> 
{ 
    List<T> innerList; 
    int maxCount; 

    public FixedSizeList(int maxCount) 
    { 
     this.innerList = new List<T>(maxCount); 
     this.maxCount = maxCount; 
    } 

    // override all the IList<T> members here by delegating 
    // to your innerList ... 
    // ... 

    public void Add(T item) 
    { 
     if (this.Count == this.maxSize) 
     { 
      throw new InvalidOperationException("No more items can be added."); 
     } 

     this.innerList.Add(item); 
    } 

    // ... 
    // ... 
} 

일종의 상용구 코드이지만 완전히 실제로 동작을 재정의하는 유일한 방법입니다.

그러나 Email 클래스를 소유하고 있지 않다면 전통적인 방법으로는 실제로 할 수 없습니다. 기본 멤버 또는 Managed Extensibility Framework과 같은 것을 대체하기 위해 반사 식 해킹이 필요합니다.

+0

환상적입니다. 감사합니다. 이것은 내 프록시에서 모든 svcutil 생성 코드 사이에 구현하는 두통이 될 것이지만 확실히 작동 할 것입니다. –

+0

svcutil.exe를 사용하는 경우/collectionType (/ ct) 옵션을 확인하십시오. 약간의 고통을 덜어 줄 수 있습니다. http://msdn.microsoft.com/en-us/library/aa347733.aspx를 참조하십시오. – bobbymcr

1

List<T>은 부분 클래스가 아니므로 자신의 부분 클래스를 사용하여 확장 할 수 없습니다.

또한, 객체에 LINQ는 그 List<T>에 의해 구현되는 IList<T> 인터페이스의 일부, 그리고 Add()List<T>의 가상 또는 추상적 인 방법이 아닙니다, 그래서 당신은 그것을 무시할 수 없습니다, List<T>Add()을 제공하지 않습니다.

살펴볼 내용은 System.Collections.ObjectModel.Collection<T>입니다.이 구성 요소는 List<T>과 비슷한 목록 구현을 제공하여 유효성 검사 작업을 수행 할 수있는 보호 된 메서드를 재정의 할 수있는 추가 기능을 제공합니다.

당신은 당신이 단지에서 상속 및 사용자 정의 규칙을 구현하는 등 InsertItem()RemoveItem() 등의 메소드를 오버라이드 (override), 처음부터 목록을 구현할 필요가 없습니다 :


using System.Collections.ObjectModel; 

public class EmailCollection : Collection<Email> 
{ 
    public int MaximumAttachments { get; set; } 

    protected override void InsertItem(int index, Email item) 
    { 
     if (Count == MaximumAttachments) 
     { 
      ... throw error 
     } 

     // do actual insert 
     base.InsertItem(index, item) 
    } 
} 

Add() 전화 후드 아래 InsertItem()합니다.

+0

'Collection '은 (IList 구현과 비교하여) 이것을위한 훨씬 간단한 구현이라고 동의한다; 물론 외부 라이브러리가'List '을 요구하면 까다로워집니다. 내부 목록을 어딘가에 노출시켜야 할 수도 있습니다 (명시 적으로 *가 목록에 있음). 그렇지 않으면 목록에있는 'List '입니다. 'List '가 디폴트 임). –

관련 문제