2011-02-11 2 views
8

그래서 저는 실제로 인수를 보내지 않고 클래스 변수를 특정 값으로 설정 한 다음 다른 방법으로 다시 사용합니다. 이것은 일을하는 "모범 사례"방법입니까? 그렇지 않다면 올바른 방법을 배우는 데 관심이 있습니다. 감사! 수/인수가 다른 방법으로 보내야합니까?이벤트 처리기를 통해 인수를 보내는 중입니까?

답변

10

Closures이 바로이 문제를 해결하기 위해 도입되었습니다. 적절한 변수를 캡처하여

, 당신은 포함하는 방법 '들보 다 오래 남았습니다'고 그것을 스토리지를 제공 할 수 있습니다 :

// Note that the 'input' variable is captured by the lambda. 
pd.PrintPage += (sender, e) => Print(e.Graphics, input); 
... 

static void Print(Graphics g, string input) { ... } 

이 대단히 편리한 기능주의 마십시오을; 컴파일러가 사용자를 대신하여이 문제를 해결하는 방법은 사용자 자신의 기존 솔루션과 의심스럽게 유사합니다. (특정 차이점이 있습니다. 예를 들어 캡쳐 된 변수가 기타() 클래스의 새로 생성 된 객체의 필드로 끝나는 경우 의 임시 저장 위치가있는 기존 솔루션이 없습니다. 좋지 않아 오히려PrintIt호출 당보다 더 클래스의 인스턴스를는 - 그것은하지 일반적으로) 예를 들어,

+0

을, 그냥 전자 대신 인수 e.Graphics를 보내 더 나은 무엇입니까? 아니면별로 큰 문제가 아닌가? – sooprise

+0

@sooprise : 그건 당신에게 달렸습니다. 전체 PrintPageEventArgs를 필요로하지 않는다고 생각 했으므로, 필요한 부분만을 알려 드리겠습니다. 미안, 어쩌면 나는 '리팩토링'을하지 말았어야했다. 그것은 실제 문제를 저해합니다. – Ani

+0

폐쇄에 관해 다른 질문이 있습니다. 단지 내 코드가 OP에서 잘못되었다는 것이 나에게 발생했습니다. 변수 "pd"는 실제로 "PrintIt"과 "PrintDocument_PrintSomething"둘 다에 사용되는 개인 클래스 변수입니다. "pd"도 "input"과 같은 인수로 전달되어야합니까? (두 개의 메소드 외부에서 정의되고 둘 다 사용되므로)? – sooprise

1

을-스레드로부터 안전하지 않습니다,하지만)이 API (윈폼 인쇄 것이 일반적인 방법입니다 .

PrintThis는 변수가 아니라 "모델"또는 "문서"라고 생각하십시오.

0

다른 방법으로, 상속 사용할 수 있습니다 인쇄 방법에서

class MyPrintDocument : PrintDocument 
{ 
    public delegate void MyPrintPageEventHandler (object, PrintPageEventArgs, object); // added context! 
    public event MyPrintPageEventHandler MyPrintPageEvent; 

    public MyPrintDocument (object context) { m_context = context; } 
    protected void OnPrintPage (PrintPageEventArgs args) 
    { 
    // raise my version of PrintPageEventHandler with added m_context 
    MyPrintPageEvent (this, args, m_context); 
    } 
    object m_context; 
} 

public void PrintIt(string input) 
{ 
    MyPrintDocument pd = new MyPrintDocument(input); 
    pd.MyPrintPage += new MyPrintPageEventHandler (PrintDocument_PrintSomething); 
    pd.Print(); 
} 

private void PrintDocument_PrintSomething(Object sender, PrintPageEventArgs e, object context) 
{ 
    e.Graphics.DrawString((string) context, new Font("Courier New", 12), Brushes.Black, 0, 0); 
} 
+0

상속은 "더 나은 연습"입니다 (클로저와 비교할 때) – sooprise

+0

@sooprise : 이것은 C#의 모든 버전에서 작동합니다. 클로저는 다음과 같습니다. 최근 소개 (3.5?). "Better Practice"에 관해서는 말하기 어렵습니다. – Skizz

+0

감사합니다. – sooprise

관련 문제