2011-09-06 4 views
3

사용자 지정 인수가있는 인터페이스에서 이벤트를 지정하려고합니다. 이벤트 인수가 객체가되어야합니다. 가능한 한 많은 코드를 제거하려고했습니다. 현재 다음 오류가 발생했습니다.C# 사용자 지정 인수가있는 이벤트

ArgumentNullException: Argument cannot be null. 
Parameter name: obj 
LittleObject.IObject.add_ChangeEvent (System.EventHandler`1 value) 
(at LittleObject.cs line : [where the comment is]) 

코드

public class ChangeEventArgs : EventArgs { 
    public ChangeEventArgs(SomeClass c){ someClass = c;} 
    public SomeClass someClass; 
} 


public interface IObject { 
    void OnChangeEvent(ChangeEventArgs e); 
    event EventHandler<ChangeEventArgs> ChangeEvent; 
} 


public class LittleObject : IObject{  

    public event EventHandler<ChangeEventArgs> ChangeEvent; 

    public fireEvent(){ 
     OnChangeEvent(new ChangeEventArgs(new SomeClass())); 
    } 

    event EventHandler<ChangeEventArgs> IObject.ChangeEvent{ 
     add{        // error here 
      lock (ChangeEvent) { 
       ChangeEvent += value; 
      } 
     } 
     remove{ 
      lock (ChangeEvent){ 
       ChangeEvent -= value; 
      } 
     } 
    } 

    public void OnChangeEvent(ChangeEventArgs e){ 
     if(ChangeEvent != null) { 
      ChangeEvent(this, e); 
     } 
    } 
} 


public class Main { 

    IObject currentObject; 

    void init(){ 
     currentObject = new IObject(); 
     currentObject.ChangeEvent += new EventHandler<ChangeEventArgs>(OnChangeEvent); 
    } 

    void doStuff(){ 
     currentObject.fireEvent(); 
    } 

    public void OnChangeEvent(object sender, ChangeEventArgs e) { 
     SomeClass someClass = e.someClass; 
    } 
} 
+0

코드가 컴파일됩니까? 인터페이스'new IObject();를 인스턴스화하려고합니다. ' – Chandu

+0

더하기 : 잠금 장치가 비싸 - 정말 필요합니까? ChangeEvent를 fireEvent 메소드 내부의 로컬 변수에 할당하여 잠금을 피하는 간단한 방법이 있습니다. –

답변

7

이 코드는 매우 혼란,하지만 난 당신이 null 관한 안내에 고정되어 있기 때문에 당신이 예외를 얻고있는 이유는 믿습니다.

당신이 할 경우 : 컴파일러는 실제로 ChangeEvent 이벤트를 백업 민간 필드을 사용

add 
{ 
    lock (ChangeEvent) { ... } 
} 

(field-like event 참조). 이 필드의 초기 값은 null (명시 적으로 초기 값이 지정되지 않았 음, 예를 들어 field-initializer를 통해)입니다.

지금 처음으로 누군가가 (해당 필드에 의해 참조되는 객체에 대한 잠금을 시도에 자물쇠를 초래하여 정의add 접근이 호출, "래핑"이벤트 (someObject.ChangeEvent += ...)에 가입 실제로 'sync-block'이라 불리는 객체 헤더에 어떤 데이터가 필요하다). 물론, 그러한 물건이 없다. 그것은 자물쇠가 쾅하는 것을 만든다.

이상한 obj 매개 변수는 Monitor.TryEnter(object obj, ref bool lockTaken)에서 비롯된 것으로 C# lock 문은 (이전 버전의 C#에서는 다른 방법을 대상으로) 컴파일됩니다.

정직하게 생각하지만이 코드 전체를 재 설계하는 것이 좋습니다.

편집 : 랩핑 이벤트의 사용을 명확히했습니다.

+0

Spot On, 건배. – user346443

관련 문제