Меня интересует может ли 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")
{
}
}
Виртуальный выделенный сервер (VDS) становится отличным выбором
Для ограничения доступа к ячейкам EXCEL через C# применяю метод WorksheetProtection
Есть 2 ViewModel это LoginViewModel и AuthViewModel В AuthViewModel идет инициализация и вызов делегата при срабатывании команды