Мне нужен способ заставить подкласс одного из моих классов объявить определенный статический метод. Например, безопасная функция типа FromFile или FromStream. Подобно концепции абстрактных методов для нестатического контекста.
Я знаю, что мог бы использовать конструкции, подобные этой:
return (T)typeof(T).GetMethod("FromFile").Invoke(null, new[] { someArgs });
Но это вызовет исключение только во время выполнения, если методне определено. Но я хочу, чтобы код не компилировался, если его там нет.
Я также знаю, что я мог бы получить все эти методы загрузчика при запуске и сохранить их в статической карте Type-Loader, но все жеэто вызовет исключение только во время запуска приложения.
В этом примере я использую загрузчик текстур, который должен иметь возможность загружать различные типы текстур, если они наследуют один и тот же базовый класс. (OpenGL Texture Wrappers, DX Texture Wrappers, Видео Текстуры и т. Д.)
public abstract class DataContainer<T>
{
public abstract T Load(object someArgs);
[...]
}
public class TextureContainer<T> : DataContainer<T> where T : Texture<T>
{
public override T Load(object someArgs)
{
if (/*is currently loaded*/)
return GetLoadedFile(someArgs);
else
return T.FromFile(someArgs);
}
[...]
}
Базовый класс для текстуры будет выглядеть примерно так:
public abstract class Texture<T> where T : Texture<T>
{
//works fine, forces derived class to declare a type safe Clone method
public abstract T Clone();
//sadly for static methods I can't do the same
//so I need another way here
public static /*abstract*/ T FromFile(object someArgs);
}
Тогда конкретная реализация текстуры будетвыглядят так:
public class DirectXTexture : Texture<DirectXTexture>
{
//works fine
public override DirectXTexture Clone()
{
throw new System.NotImplementedException();
}
//another way needed
public static /*override*/ DirectXTexture FromFile()
{
throw new System.NotImplementedException();
}
}
Имея эту настройку, вы можете просто получить текстуру, используя следующий код с базовой загрузкой DataContainer и при необходимости выгружая текстуру или выполняя задачу загрузки в фоновом потоке.
static class Program
{
static void Main(string[] args)
{
var container = new TextureContainer<DirectXTexture>();
var tex = container.Load("some file");
}
}
Просто для пояснения: у меня уже есть полностью работающая конструкция DataContainer, которая может загружать ресурсы в основных или фоновых потоках и отслеживать экземпляры, которые ссылаются на мои ресурсы, чтобы я мог выгружать их, если они больше никому не нужны. Единственное, что мне нужно, это функциональность создания контейнера для типа ABSTRACT с соответствующими им методами загрузки, поэтому мне не нужно создавать отдельный подкласс для DXTextureContainer, GLTextureContainer, VideoTextureContainer и т. Д.
Надеюсь, вы, ребята, ребятаможет помочь мне здесьЗаранее спасибо!