2014-11-29 2 views
1

이 온라인 검색을 시도했지만 운이 지금까지 기본적으로동적 조건

나는 사용자가 TargetAboutToUsePotion에게 TargetHealthLessThen20

이이 열거에 저장됩니다 같은

와 같은 선택의 표현을 만들 수없는 경우

"TargetHealthLessThen20 || TargetAboutToUsePotion"

과 같은 문자열 식으로 데이터베이스에 저장됩니다.

지금 나는 이러한 방법을 호출하는 동적했다 IF 문을 쓸 수 있기를 원하는

public bool IsTargetHealthLessThen20(Target target) 
{ 
     // do login 
} 

public bool IsTargetAboutToUsePotion(Target target) 
{ 
    // do login 
} 

즉 그것의 실행 조건을 확인하고 같은

if("IsTargetHealthLessThen20(target) || IsTargetAboutToUsePotion(target)") 
{ 
     // Perform Action 
} 
로 conditons에 넣어 각 열거하는 방법을

이것에 대해 가장 좋은 방법에 대한 아이디어가 있습니까?

답변

0

나는 그것이 바람직하지 않다고 생각합니다. 목표 매개 변수 값을 알지 못하기 때문입니다. 매개 변수 값을 알고있는 경우 식 호출로 reflect 호출 메서드를 사용할 수 있습니다.

0

나는 과거에 거의 똑같은 일을 필요로하기 때문에, 당신이 찾고있는 바로 답을 줄 생각

당신이 무엇을 같이 취급 할 필요가 있도록, C# 코드가 무엇을 가지고

  1. 지금 내가 컴파일 당신이 거기있는 텍스트를 사용

    interface ICondition { bool Evaluate(); }

  2. 같은 인터페이스를 만들기 :)입니다 수업에 들지 마라. 마찬가지로 : using YourProgramNamespace; class myCondition : ICondition { bool Evaluate() { return {0} ; } } 더 많은 매개 변수를 전달하려면 일치하는 매개 변수를 허용하도록 인터페이스를 변경하십시오. 원하지 않는 경우 여러 개의 인터페이스는 이런 식으로합니다

    이 텍스트에서

    using YourProgramNamespace; class myCondition : ICondition { bool Evaluate(params object[] parameters) { return {0} ; } } 당신은 그럼 그냥 이런 식으로 쓰기 : TargetHasLessThan20Hp ((은 TargetType) 매개 변수 [0])

{0}을 이미 가지고있는 조건 텍스트로 대체하십시오.

  1. 코드를 컴파일하려면 C# 컴파일러를 사용하십시오. http://msdn.microsoft.com/de-de/library/microsoft.csharp.csharpcodeprovider%28v=vs.110%29.aspx 사용법에 대한 튜토리얼 이상이 있으며 사용법이 그리 어렵지 않습니다.

  2. 클래스를 Dll로로드하고 리플렉션으로 유형을 찾으면이 또한 어렵지 않으며 많은 튜토리얼이 있습니다. 그냥 당신 Assembly.GetTypes()를 사용하여 거기에서 이동

  3. Activator를 사용하십시오.당신이 가지고있는 타입을 인스턴스화하기위한 CreateInstance

  4. 그런 다음 evaluate 함수를 호출하면 true 또는 false가 반환됩니다.

  5. 성능 향상을 위해 조건문이 실제로 변경 될 때까지 매번 컴파일하지 마십시오.

자세한 정보가 필요합니까? 물어 보면 내 대답을 편집하거나 의견에 게시 할 것입니다.

1

성능상의 이유로 다음을 권장하지는 않지만 원하는대로 할 수 있습니다.

대상을 항상 적용하는 경우 평가 방법 클래스를 미리 정의한 다음 문자열 메서드 이름 목록을 전달하여 해당 메서드를 평가할 수 있습니다.

void Main() 
{ 
    var inputs = new List<string>(); 
    inputs.Add("MethodA"); 
    inputs.Add("MethodB"); 

    var results = Evaluate(inputs, "target"); 
    Console.WriteLine(results); 
} 

public bool Evaluate(List<string> predicates, string target) 
{ 
    var methods = new Methods(); 

    var tempResult = false; 

    foreach (var pred in predicates) 
    { 
     var method = methods.GetType().GetMethod(pred); 
     if (method == null) 
     throw new InvalidOperationException(
      string.Format("Unknown method {0}.", pred)); 

     tempResult = (bool)typeof(Methods).GetMethod(pred).Invoke(methods, new [] {target}); 
     if (!tempResult) break; 

     continue; 
    } 

    return tempResult; 
} 

public class Methods 
{ 
    public bool MethodA(string target) 
    { 
     return target == "target"; 
    } 

    public bool MethodB(string target) 
    { 
     return target == "not a target"; 
    } 
} 

이 특정 평가 기능은 AND 조건을 평가합니다. OR 조건에 대한 평가 논리를 변경해야합니다. 이론적으로 문자열을 검사하고 문자열의 연산자에 따라 다른 메서드를 호출 할 수 있습니다.

편집

방법 자체에 당신의 방법에 대한 귀하의 문자열 이름을 매핑하는 사전을 생성하는 것입니다 반사를 방지 할 두 번째 옵션을 선택합니다. 이렇게하면 리플렉션 없이도 동일한 결과를 얻을 수 있지만 사전을 동기화해야합니다. 반면, 리플렉션 오버 헤드없이 컴파일 시간을 추가로 확보 할 수 있습니다.

private static readonly Methods _methodsInstance = new Methods(); 

private static Dictionary<string, Func<string, bool>> _methods = new Dictionary<string, Func<string, bool>>() 
{ 
    { "MethodA", _methodsInstance.MethodA }, 
    { "MethodB", _methodsInstance.MethodB }, 
}; 

public bool Evaluate(List<string> predicates, string target) 
{ 
    var tempResult = false; 

    foreach (var pred in predicates) 
    { 
     tempResult = _methods[pred](target); 
     if (!tempResult) break; 
     continue; 
    } 

    return tempResult; 
}