У меня есть настраиваемая среда MVC, в которой я переделываю API маршрутизации. Я пытаюсь придумать чистый способ разделить «настройку» и «выполнение» в моей структуре, который широко использует делегаты и обобщения. Прямо сейчас я представляю себе это со стороны звонящего:
//setup
MyRouter.AddRoute("/foo", () => new MyHandler(), (h) => h.MyMethod);
//h.MyMethod only exists in MyHandler, not in HttpHandler
//execution
MyRouter.Execute(HttpContext);
Сейчас я могу заставить подпись метода AddRoute "работать":
delegate T HandlerInvoker<T>();
delegate string HandlerCallMethod<T>(T handler);
...
public void AddRoute<T>(string pattern, HandlerInvoker<T> invoker, HandlerCallMethod<T> caller) where T is HttpHandler{...}
Если бы мне не нужно было хранить вызывающего и вызывающего, и я мог бы делать это правильно, это сработало бы нормально. Но мне нужно сохранить вызывающий и вызывающий для последующего выполнения.
Текущие вещи, о которых я думал:
- Сохранение их в
List<object>
и последующее использование отражения для их вызова. Это кажется чрезвычайно сложным и, вероятно, не слишком эффективным. - Перевод
AddRoute
в исполнение. Это может усложнить использование моего API, но может оказаться моим единственным "хорошим" выбором. - Задайте ТАК вопрос :)
Есть ли какой-нибудь хороший способ сохранить эти общие типы без множества мучительных размышлений?
1 ответ
Вы можете сохранить анонимного делегата, который выполняет все преобразования за вас.
Похоже, сработает следующее (никак не проверено):
List<Action> handlers;
handlers.Add(() => caller(invoker()));
Учтите, что это не сработает, если бы вы кешировали invoker
.
В этом случае вам нужно сохранить значение, Lazy
должно помочь.
List<Action> handlers;
Lazy<T> lazy = new Lazy<T>(invoker);
handlers.Add(() => caller(lazy.Value);
Последний будет создавать только один экземпляр возвращаемого значения invoker
за каждый вызов метода. А поскольку lazy
является локальной переменной, она автоматически помещается в класс, который сохраняется до тех пор, пока handlers
удерживает ссылку для вас.
Обратите внимание, что я проигнорировал шаблон, но, похоже, вам здесь не нужна помощь.
Похожие вопросы
Новые вопросы
c#
C# (произносится как «see Sharp») — это высокоуровневый мультипарадигменный язык программирования со статической типизацией, разработанный Microsoft. Код C# обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, которое включает в себя .NET, .NET Framework, .NET MAUI и Xamarin среди прочих. Используйте этот тег для ответов на вопросы о коде, написанном на C#, или о формальной спецификации C#.
var h=invoker(); ... h.Foo="bar" etc.. caller(h)