簡體   English   中英

在 C# 中調用具有方法屬性的非靜態方法

[英]Call non-static methods with method attributes in C#

我目前有一個工作系統,當 static 方法具有事件屬性和事件類型的單個參數時,它可以由 EventSystem 調用。

示例方法

[EventAtribute]
public static void thisIsAnEventHandler(Event ev)
{
  print(ev.ToStrring());
}

當我調用此 function 時,它會獲取具有此事件類型的所有方法並調用它, MethodInfo.Invoke 采用 null 的 obj,因為所有方法都是 ZA81259CEF8E959C624DF1D456E5D3297

public static void callMethodsWithEvent(Event ev)
        {
            // triggers when initEventSystem has not been called
            Debug.Assert(_eventMethods != null);
            
            var methods = _eventMethods
            .Where(x => x.GetParameters()[0].ParameterType == ev.GetType())
            .Where(x => x.GetParameters().Length == 1)
            .Where(x => x.IsStatic);

            foreach (var method in methods) // iterate through all found methods
            {
                method.Invoke(null, new object[] {ev});
            }
        }

所有方法在啟動時如何存儲

public static void initEventSystem()
        {
            _eventMethods = AppDomain.CurrentDomain
                .GetAssemblies() // Returns all currenlty loaded assemblies
                .SelectMany(x => x.GetTypes()) // returns all types defined in this assemblies
                .Where(x => x.IsClass) // only yields classes
                .SelectMany(x => x.GetMethods())
                .Where(x => x.GetCustomAttributes(typeof(EventAtribute), false).FirstOrDefault() != null)
                .ToList();
        }

即使這個系統運行良好,它也只適用於 static 方法。 我知道我需要將 object 引用傳遞給 Invoke 方法,但我希望能夠創建事件並讓帶有該事件的任何方法被調用,而無需我考慮它。

所以我認為我需要的是能夠使用此方法簽名獲取所有 object 並在所有這些對象中單獨調用所有這些方法。 有沒有辦法在不遍歷堆的情況下做到這一點。

謝謝。

有了上面的評論,我建議了一個如下的解決方案(只是一個廣泛的想法,實現需要更多細節)。 是的,接口只提供方法,沒有實現。 但這和委托完全一樣,也只是定義了如何調用某個方法,而不是實現本身。 接口實際上可以看作是連接在一起的委托集合。

創建一個可以附加到類的屬性,告訴您的事件系統這些類可以接收某些事件:

    /// <summary>
    /// Declares the visibility of a component.
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
    public sealed class InterfaceSupportAttribute : Attribute
    {
        private Type[] m_supportedInterfaces;

        public InterfaceSupportAttribute()
        {
            m_supportedInterfaces= new Type[0];
        }

        public Type[] SupportedInterfaces
        {
            get => m_external;
            set => m_external = value.Distinct().ToArray();
        }
    }

使用如下:


public interface IMyFunctionality
{
    public void Foo();
}

[InterfaceSupportAttribute(SupportedInterfaces = new[] {typeof(IMyFunctionality)}) 
public class MyClass : IMyFunctionality
{
   public MyClass() {...}
   public void Foo() {...}
}

然后,在代碼的其他地方:


MyClass c = new MyClass();
RegisterType(c);

RegisterType function 提取屬性並保留對 class 的引用。 然后使用另一個 function 查詢所有實現IMyInterface的類。 您可以自己實現這些功能,也可以使用現有的依賴注入框架,例如 NInject。 這些提供了注冊類(及其接口)和查詢注冊類以獲取特定接口的功能。

注意:我從未使用過 unity,但我實際上假設它已經包含這樣的依賴注入框架,因為許多較大的軟件包以一種或另一種形式使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM