Абстрактный generic класс, с переменным числом типов

155
19 февраля 2019, 18:00

Меня интересует может ли generic класс принимать несколько типов параметров, а точнее которое заранее неизвестно, как тот же кортеж?

Т.е. на данный момент у меня есть 2 класса, с одним именем, но при этом они оба абстрактные, и один из них не является generic'ом.

public abstract class SafeLibrary : SafeHandleZeroOrMinusOneIsInvalid
{
    private Dictionary<string, Delegate> _cashedFunctions;
    public string ModulePath { get; }
    private SafeLibrary() : base(true)
    {
        _cashedFunctions = new Dictionary<string, Delegate>();
    }
    protected SafeLibrary(string modulePath) : this()
    {
        handle = WinApi.LoadLibrary(modulePath);
        if (handle == IntPtr.Zero)
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        ModulePath = modulePath;
    }
    protected override bool ReleaseHandle()
    {
        bool result = WinApi.FreeLibrary(handle);
        handle = result ? IntPtr.Zero : handle;
        if (!result)
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        _cashedFunctions.Clear();
        _cashedFunctions = null;
        return result;
    }
    public T GetInteropDelegate<T>() where T : Delegate
    {
        Type type = typeof(T);
        if (type.GetCustomAttributes(typeof(UnmanagedFunctionPointerAttribute), false).Length == 0)
        {
            throw new AttributeNotFoundException($"Attribute with type {typeof(T).FullName} has no UnmanagedFunctionPointerAttribute!");
        }
        object[] attributes = type.GetCustomAttributes(typeof(CFunctionAttribute), false);
        if (attributes == null || attributes.Length == 0)
        {
            throw new AttributeNotFoundException($"Attribute with type {typeof(T).FullName} has no CFunctionAttribute!");
        }
        string funcName = (attributes[0] as CFunctionAttribute).Function;
        if (_cashedFunctions.ContainsKey(funcName))
        {
            return (T)_cashedFunctions[funcName];
        }
        T result = Marshal.GetDelegateForFunctionPointer<T>(WinApi.GetProcAddress(handle, funcName));
        _cashedFunctions.Add(funcName, result);
        return result;
    }
}
public abstract class SafeLibrary<DependsModule> : SafeLibrary where DependsModule : SafeLibrary, new()
{
    public DependsModule DependedModule
    {
        get;
    }
    protected SafeLibrary(string modulePath) :
        base(modulePath)
    {
        DependedModule = new DependsModule();
    }
}

Таким образом, можно избавиться от необходимости ручной подгрузки необходимых зависимостей библиотеки:

class MySafeLibraryClass : SafeLibrary
{
    public MySafeLibraryClass() : base("SomePathToNeededModule.dll")
    {
    }
}
class MySafeLibraryClassWithDepends : SafeLibrary<MySafeLibraryClass>
{
    public MySafeLibraryClassWithDepends() : base("SomePathToNeededModule.dll")
    {
    }
}

Но, что если у библиотеки (одной) имеется несколько зависимостей, заново подгружать эти библиотеки вручную?

В общем, хотелось бы иметь примерно такой вид:

class MySafeLibraryClass : SafeLibrary
{
    public MySafeLibraryClass() : base("SomePathToNeededModule.dll")
    {
    }
}
class MySafeLibraryClass2 : SafeLibrary
{
    public MySafeLibraryClass() : base("SomePathToNeededModule2.dll")
    {
    }
}
class MySafeLibraryClass3 : SafeLibrary
{
    public MySafeLibraryClass() : base("SomePathToNeededModule3.dll")
    {
    }
}
class MySafeLibraryClassWithDepends : SafeLibrary<MySafeLibraryClass, MySafeLibraryClass2, MySafeLibraryClass3> // и т.д. Заранее неизвестно сколько зависимостей.
{
    public MySafeLibraryClassWithDepends() : base("SomePathToNeededModuleWithDepends.dll")
    {
    }
}
READ ALSO
Составной диапазон из разных ячеек EXCEL (C#)

Составной диапазон из разных ячеек EXCEL (C#)

Для ограничения доступа к ячейкам EXCEL через C# применяю метод WorksheetProtection

175
Проблема с срабатыванием события c# wpf mvvm

Проблема с срабатыванием события c# wpf mvvm

Есть 2 ViewModel это LoginViewModel и AuthViewModel В AuthViewModel идет инициализация и вызов делегата при срабатывании команды

170
Как скрыть метод базового класса?

Как скрыть метод базового класса?

У меня есть класс WsEvent:

174