2010-07-30 6 views
7

무엇 (있는 경우), 아래의 방법으로 클래스의 비 정적 메소드를 호출하는 등락 (성능, 좋은 코딩 연습, 쓰레기 수집 등)이다호출 비 정적 메소드

new ClassA().MethodA(param1, param2); 

ClassA classA = new ClassA(); 
classA.MethodA(param1, param2); 

어떤 생각의 더 "전통적인"방식에 대한 같은

주시면 감사하겠습니다.

+0

ClassA는 관리되지 않는 리소스를 만들거나 IDisposable을 구현합니까? – SwDevMan81

답변

10

연습을 코딩
으로 코딩, 두 번째 옵션은 더 나은, 객체가 첫 번째 변수에 저장된다. 더 나은 이유는 사용 된 컨텍스트에 따라 개체의 이름을 지정해야하기 때문입니다. 예를 들면 :

var pendingUserForRegistration = new User(); 

성능
는 지역 변수에 객체의 저장을 스택에서 직접 객체를 사용하여 생략하기 때문에, 첫 번째 옵션이 약간 더 좋을 수 성능에 관해서는 .이는 방법의 IL에서 볼 수있다 : 제

IL : 초

.maxstack 8 
L_0000: nop 
L_0001: newobj instance void NS.ClassA::.ctor() 
L_0006: call instance void MS.ClassA::M() 
L_000b: nop 
L_000c: ret 

IL :

.maxstack 1 
.locals init (
    [0] class NS.ClassA c) 
L_0000: nop 
L_0001: newobj instance void NS.ClassA::.ctor() 
L_0006: stloc.0 
L_0007: ldloc.0 
L_0008: callvirt instance void NS.ClassA::M() 
L_000d: nop 
L_000e: ret 

이것은 보통 작은 성능 오버 헤드는, 그것의 실제 성능 문제를 해결할 수있는 경우를 찾기가 어렵습니다.
부호 이득의 유지 보수성이있어 성능이 의미 이름의 변수에 객체를 저장하는 것이 바람직있어 이득보다 크므


결론.

+1

Thanks Elisha. 우수한 상세 답변. 정확히 내가 필요로하는 것. –

+0

또한 @ SwDevMan81의 질문에 대한 힌트가 있습니다. 사용중인 객체가 일회용이면 나중에 변수를 처리 할 수 ​​있도록 변수에 넣고 싶을 것입니다. 첫 번째 방법을 사용하면 클린업에 오브젝트의 파이널 라이저 (finalizer)가 놓이게됩니다. – JohnLBevan

3

아무런 차이가 없습니다. 이 상황에서 정적 방법이 더 적절할 것입니다.

+0

불행히도 내 영향력이 해당 클래스 수정 에까지 미치지 않는다는 것에 동의합니다. :) 또한 멀티 스레딩을 관리하기 다소 어려워집니다 –

0

일반적으로 클래스를 "알"필요가없는 경우 정적 메서드를 사용합니다. 클래스가 자신과 자신의 상태를 알아야 할 때 인스턴스 메서드를 사용합니다.

다소 차이가 있습니다.

1

다른 용도로 ClassA를 사용하지 않을 경우 new ClassA().MethodA(param1, param2);은 정상입니다. 그렇지 않으면 좀 더 전통적인 인스턴스화를 선택해야합니다. ClassA classA = new ClassA();

+0

의미가 있습니다. 신속한 대응에 감사드립니다. –

0

나는 전화 사이트에서 왜 이렇게하고 싶은지 묻습니다. 주위를 둘러 볼 수없는 경우 new ClassA().MethodA(a,b)을 정적 방법으로 묶어 통화 사이트의 코드 노이즈를 피하는 것이 좋습니다.

+0

흠 ... 그러면 멀티 스레딩을 관리하는 것이 까다로워집니다. –

0

이들은 동일합니다. 첫 번째 접근법은 한 줄의 코드 줄임을 의미합니다. MethodB을 호출하기 위해 코드를 수정해야하는 경우 두 번째 접근 방식이 약간 더 멋지다.

+0

두 번째 지점에서 의미가 있습니다. 아마 컴파일러는 어쨌든 두 방법 모두를 해결합니다. 신속한 답변을 주셔서 감사합니다. –

1

차이점이 없습니다. 그러나 ClassAIDisposable을 구현하는 경우 모두 나쁜 아이디어입니다.

+0

빠른 응답을 보내 주셔서 감사합니다. ClassA가 IDisposable을 구현한다면, 반발은 무엇입니까? –

+0

'ClassA'가'IDisposable'을 구현하는 경우 수동으로 또는'using' 문을 통해 인스턴스가 더 이상 필요하지 않을 때'Dispose' 메소드를 호출해야합니다. 이렇게하지 않으면 코드가 (ClassA가 무엇을하는지에 따라) 관리되지 않는 리소스가 누출 될 수 있습니다. –

+0

고마워, 프레드릭. 나는 그 정화에 감사드립니다. –

2

백엔드에는 차이가 없습니다. CIL에서는 ClassA 객체를 만든 다음 메서드를 호출합니다. 두 코드 모두 동일한 CIL로 변환되므로 성능 차이가 전혀 없습니다.

+0

고마워 Scott, 내가 궁금해하는 것이있다. –

1

둘은 동일합니다. 사실 컴파일러가 각각에 대해 동일한 IL을 생성 할 가능성이 있습니다.

전통적인 방법은 디버깅에서 이점입니다. 문제가 ctor 또는 MethodA에있는 경우 확신 할 수 있습니다. 또는 MethodA가 객체를 변경하고 객체를 검사해야하는 경우.

+0

디버깅은 좋은 점입니다. 감사합니다 James –

0

첫 번째 방법은 ClassA의 인스턴스를 생성해야합니다 (클래스가 지금까지 사용되지 않은 경우 클래스 정의를 메모리에로드하는 것 외에). 두 번째 방법은이 추가 객체 인스턴스화와 클래스의 다음 가비지 수집을 피합니다.

수천 번이 아니라 수시로 발생하면 걱정하지 않으셔도됩니다. 그러나 클래스 인스턴스 메서드 나 속성에 액세스 할 필요가없는 경우 정적 메서드를 구현하는 것이 더 깨끗한 디자인이됩니다.

경우에 따라 약간 다른 접근법이 있습니다. ClassA에는 개인 필드 또는 메소드에서 사용하게 될 속성을 초기화하는 인수가 생성자에 필요하다고 가정합니다. 이 경우 첫 번째 방법은 필수 항목입니다.

new ClassA(param0).MethodA(param1, param2); 

하지만 그 방법은 추가 매개 변수를 사용하기 위해 다시 정의 할 수 있습니다.

관련 문제