2010-04-12 3 views
4

C#을 사용하면 함수 C() 바로 전에 함수 A()이 호출 된 경우 약간의 추가 작업이 필요합니다. A()C() 사이에 다른 함수가 호출 된 경우 추가 작업을하고 싶지 않습니다. 최소한의 코드 중복을 필요로하는 아이디어는 있습니까?C#에서 다른 메서드가 호출되면 부울을 자동으로 다시 설정하려면 어떻게해야합니까?

모든 기능에 flag = false;과 같은 줄을 추가하는 것을 피하려고합니다. B1 .. BN.

여기에 매우 기본적인 예입니다

위의 예는 단순한 케이스를 사용했지만, 난이 논리 값이 아닌 다른 뭔가를 사용하여 열려있어
bool flag = false; 

void A() 
{ 
    flag = true; 
} 

void B1() 
{ 
    ... 
} 

void B2() 
{ 
    ... 
} 

void C() 
{ 
    if (flag) 
    { 
     //do something 
    } 
} 

. 중요한 것은 일종의 플래그를 설정하고 재설정하여 C()이 그에 따라 행동하는 방법을 알고 싶어한다는 것입니다.

도움 주셔서 감사합니다. 설명이 필요한 경우 내 게시물을 편집합니다.

+1

여러 스레드가 A를 호출 할 예정입니까? 즉, 스레드로부터 안전 할 필요가 있습니까? – womp

답변

1

단순한 상태 머신을 제자리에 두어 유사한 상황 (즉, A가 C보다 먼저 호출되었는지 여부를 알아야 할 필요성)이있는 문제를 해결했습니다. 기본적으로 enum 및 상태를 관리/쿼리하는 속성을 사용하여 상태 개체를 만들었습니다. (A)의 내 상당()가 호출 될 때

, 그것은 호출되었음을 나타내는 상태 오프 비즈니스 로직 조각 저장소를 가질 것이다. 다른 메소드 (B 's)가 호출 되었다면, 상태를 다른 몇 가지 상태 중 하나로 전환 할 것입니다 (제 상황이 좀 더 복잡했습니다). 그리고 C()가 호출되었을 때, 비즈니스 로직 부분을 질의하여 "A가 방금 호출 된 경우에만"기능을 보유한 D() 메서드를 호출하려고했습니다.

나는이 문제를 해결하기 위해 여러 가지 방법이 있습니다 생각하지만, 나는 처음에 더 복잡한 다중 상태 상황을 처리 할 수있는 바이너리 상황 무엇 확장 나를 수 있기 때문에이 걸린 상태 시스템 접근 방식을 좋아했다.

멀티 스레딩이 제 경우에는 문제가되지 않았기 때문에 상황이 더욱 재미있어 졌기 때문에 운 좋게도 상태 머신이 해당 시나리오에서도 잘 작동 할 것입니다.

그냥 내 두 센트.

+0

그것은 비슷한 것으로 그것을 해결할 수있었습니다. 열거 형을 사용하여 함수 A()와 C()를 결합 할 필요가없는 더 깨끗한 솔루션을 찾았습니다. – gtaborga

7

"추가 작업"을 메모 기능 (즉, 결과를 캐시하는 기능)에 포함시키는 것이 왜 좋을까요? 이 작업이 필요할 때마다 캐시를 ​​최신 상태로 유지할 수있는이 함수를 호출하면됩니다. 작업이 오래 될 때마다 캐시를 ​​무효화하십시오. 위의 약간 이상한 예에서는 각각의 Bs와 C에서 하나의 함수 호출이 필요하다고 가정합니다. A 로의 호출은 캐시를 무효화합니다.

(예 : 모든 기능 호출을 수신하고이 호출을 삽입하는 영리한 방법)을 찾고 있다면 정말 걱정할 필요가 없습니다. 나는 미친 런타임 리플렉션 프록시 클래스 생성을 생각할 수 있지만 코드 플로우를 명확하고 분명하게 만들어야합니다. 각 기능이 이미 완료된 작업에 의존하면 각 작업에서 "doWork"를 호출하십시오.

+0

그래, 나는 이것을 할 쉬운 방법이 없다고 생각했다. 함수는 어떤 순서로든 호출 될 수 있습니다. 여분의 작업이 필요한 A(), C()의 특정 순서 일 뿐이지 만 A()에서 플래그를 설정하고 B1() 또는 B2()가 C()에서 호출 될 때 재설정하지 않는 경우, 나는 잘못된 행동을한다. – gtaborga

+1

+1 반사에 대한 참조; 그리고 "미친"라벨을 붙이기 위해,이 경우 매우 정확합니다.) –

3

하나의 메서드를 호출하면 다른 개체의 동작이 변경되어 올바른 순서로 호출해야하므로 디자인과 비슷한 사운드가 너무 밀접하게 결합됩니다. 그것은 주요 붉은 깃발입니다.

일부 리펙토링과 같은 사운드가 순서에 있습니다. 실제 코드를 더 이상 보지 않고 조언을하는 것은 약간 까다 롭지 만 여기에 올바른 방향이 있습니다.

은과 같이 C에 매개 변수를 추가하는 것을 고려 :

물론 "DoExtraWork"의
void C(bool DoExtraWork) { 
    if (DoExtraWork)... 
} 

는 호출자의 맥락에서 의미있는 무언가를 지정해야합니다.

+0

비슷한 코딩 패턴을 보았습니다. * 경우에 따라 *, 그들은 정당화됩니다. 결국, 메서드의 동작을 클래스의 상태에 의존하는 것은 * 합리적입니다 : P –

0

나는 이것을하지 않는 것이 좋습니다,하지만 도대체 무엇을 : 당신은 대체하고자하는 경우 모든 간단한 방법은 호출

A(); 

을 ... 구문을 다음과 같이 :

// _lastAction is a class-level Action member 
(_lastAction = new Action(A)).Invoke(); 

은 ... 다음 C() 안에 당신은이 같은 검사를 수행 할 수 있습니다

void C() 
{ 
    if (_lastAction.Method.Name == "A") 
    { 

    } 
} 

을이 아마 THRE 아니다 ad-safe (그리고 약간의 수정없이 obfuscator를 통해 실행되는 코드에서는 작동하지 않을 것입니다.) 그래서 무거운 테스트없이 이와 같은 것을 사용하지 않을 것입니다. 나는 또한이 기간 같은 것을 사용하지 않을 것이다.

참고 : 당신이 너무 거기에 붙어 그래서 만약 C#을 내 고대 버전은이 방법을 사용하려면 각 방법에 더미 매개 변수를 추가해야 할 것, Action<T> (그리고 Action 또는 Action<T, T> 등)이있다 .

+0

나는 이런 종류의 물건이 지옥처럼 지저분하다는 것에 동의한다. 당시로서는 좋은 해결책을 생각하지 못했지만 혼란없이 일하는 것을 발견했습니다. 당신의 노력에 감사드립니다. – gtaborga

관련 문제