Tono Nam
그는 물었다 8년 전
100

Static method 와 호출하십시오 반사

나는 '등 여러 정적 클래스 중 이름공간이 미소루티언스마크로스'

static class Indent{    
     public static void Run(){
         // implementation
     }
     // other helper methods
}

  • 그래서 내 질문은 호출하십시오 반사 가능* 도움으로 그 방법을 어떻게 할 수 있을 것이라고 말했다

그럼 내가 할 수 있는 방법을 정적임 않을 경우 다음과 같은 항목을

var macroClasses = Assembly.GetExecutingAssembly().GetTypes().Where( x => x.Namespace.ToUpper().Contains("MACRO") );

foreach (var tempClass in macroClasses)
{
   var curInsance = Activator.CreateInstance(tempClass);
   // I know have an instance of a macro and will be able to run it

   // using reflection I will be able to run the method as:
   curInsance.GetType().GetMethod("Run").Invoke(curInsance, null);
}

정적 클래스 같은 내아기마저도 유지합니다. 그렇게 할 수 있는 정적 메서드는 비슷한 상황이 어떻게 됩니까?

    • 내아기마저도 한 마디로 모든 메소드가 모두 같은 걸 실행하십시오 미소루티언스마크로스트 이름공간이 있는 정적 클래스

답변 3 개

설명서 메트로딘포.2 보크 상태에 따라 정적 메서드는 그냥 지나칠 수 있도록 위한 첫 번째 인수가 무시됨 nulll.

foreach (var tempClass in macroClasses)
{
   // using reflection I will be able to run the method as:
   tempClass.GetMethod("Run").Invoke(null, null);
}

이 방식은 정적임 셀명 방향점 아웃해야 수행할 수 있도록 하고 있다 '' 를 호출할 때 제메트로트 수 있습니다.

tempClass.GetMethod("Run", BindingFlags.Public | BindingFlags.Static).Invoke(null, null);

Daniel A. White
그는 8년 전 댓글을 달았습니다
4

플래그 '일부' 를 제메트로트 바인딩하면 전달하십시오 할 수 있습니다.

ErikE
그는 5년 전 댓글을 달았습니다
2

'없이' 빈딩플라그스.스태틱 성공적으로 할 수 없는 내려받습니다 방법을 1 위를 차지했다.

J. Ouwehand
그는 일 년 전 댓글을 달았습니다
1

조상 클래스용 빈딩플라그스.플랫엔히라르치 있는 경우 방법을 추가할 수 있습니다.

정말, 정말, 정말 수 많은 코드를 작성하는 위임합니다 최적화합니다 지불한다면 가격은 한 번만 (there& # 39, s 도 정적 클래스의 메서드를 호출할 수 있는 인스턴스화하지 필요 없음). # 39, ve done, 그냥 아주 비슷한 i& 캐시에는 사람에게 이 &quot Run"; 방법을 통해 helper class :-). It 다음과 같습니다.

static class Indent{    
     public static void Run(){
         // implementation
     }
     // other helper methods
}

static class MacroRunner {

    static MacroRunner() {
        BuildMacroRunnerList();
    }

    static void BuildMacroRunnerList() {
        macroRunners = System.Reflection.Assembly.GetExecutingAssembly()
            .GetTypes()
            .Where(x => x.Namespace.ToUpper().Contains("MACRO"))
            .Select(t => (Action)Delegate.CreateDelegate(
                typeof(Action), 
                null, 
                t.GetMethod("Run", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)))
            .ToList();
    }

    static List<Action> macroRunners;

    public static void Run() {
        foreach(var run in macroRunners)
            run();
    }
}

이 방법이 훨씬 빠릅니다.

이 경우 다른 방법을 서명입니다 액션을 대체할 수 있는 방송 유형 및 메리 페로프 작업에서 필요한 작업 및 func 일반 종류, 선언해야 위임합니다 및 사용한다. 내 스스로 구축상의 /dev/raw/raw1 Func&lt, 개체, string&gt. 예쁜 인쇄하십시오 위해 안내선:

static class PrettyPrinter {

    static PrettyPrinter() {
        BuildPrettyPrinterList();
    }

    static void BuildPrettyPrinterList() {
        printers = System.Reflection.Assembly.GetExecutingAssembly()
            .GetTypes()
            .Where(x => x.Name.EndsWith("PrettyPrinter"))
            .Select(t => (Func<object, string>)Delegate.CreateDelegate(
                typeof(Func<object, string>), 
                null, 
                t.GetMethod("Print", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)))
            .ToList();
    }

    static List<Func<object, string>> printers;

    public static void Print(object obj) {
        foreach(var printer in printers)
            print(obj);
    }
}

내가 포지셔닝하십시오 간단하게.

private void _InvokeNamespaceClassesStaticMethod(string namespaceName, string methodName, params object[] parameters) {
    foreach(var _a in AppDomain.CurrentDomain.GetAssemblies()) {
        foreach(var _t in _a.GetTypes()) {
            try {
                if((_t.Namespace == namespaceName) && _t.IsClass) _t.GetMethod(methodName, (BindingFlags.Static | BindingFlags.Public))?.Invoke(null, parameters);
            } catch { }
        }
    }
}

사용.

    _InvokeNamespaceClassesStaticMethod("mySolution.Macros", "Run");

하지만 이런 고민 좀 더 강력한 무언가를 찾는 등 you& # 39, 예외 처리.

private InvokeNamespaceClassStaticMethodResult[] _InvokeNamespaceClassStaticMethod(string namespaceName, string methodName, bool throwExceptions, params object[] parameters) {
    var results = new List<InvokeNamespaceClassStaticMethodResult>();
    foreach(var _a in AppDomain.CurrentDomain.GetAssemblies()) {
        foreach(var _t in _a.GetTypes()) {
            if((_t.Namespace == namespaceName) && _t.IsClass) {
                var method_t = _t.GetMethod(methodName, parameters.Select(_ => _.GetType()).ToArray());
                if((method_t != null) && method_t.IsPublic && method_t.IsStatic) {
                    var details_t = new InvokeNamespaceClassStaticMethodResult();
                    details_t.Namespace = _t.Namespace;
                    details_t.Class = _t.Name;
                    details_t.Method = method_t.Name;
                    try {
                        if(method_t.ReturnType == typeof(void)) {
                            method_t.Invoke(null, parameters);
                            details_t.Void = true;
                        } else {
                            details_t.Return = method_t.Invoke(null, parameters);
                        }
                    } catch(Exception ex) {
                        if(throwExceptions) {
                            throw;
                        } else {
                            details_t.Exception = ex;
                        }
                    }
                    results.Add(details_t);
                }
            }
        }
    }
    return results.ToArray();
}

private class InvokeNamespaceClassStaticMethodResult {
    public string Namespace;
    public string Class;
    public string Method;
    public object Return;
    public bool Void;
    public Exception Exception;
}

사용은 거의 똑같은.

_InvokeNamespaceClassesStaticMethod("mySolution.Macros", "Run", false);

dynamichael
D Stanley
그는 2년 전 댓글을 달았습니다
1

일반적으로 모든 가능한 예외는 삼키기 나쁜 발상이다.

dynamichael
그는 2년 전 댓글을 달았습니다
0

참. 게으른 것은 단순한. # 39, ve i& 향산된 my answer.

Nelly
그는 2년 전 댓글을 달았습니다
3

청소하시겠습니까 풍선이거나 단순 코드를 읽을 수 없습니다.