Я пытаюсь работать Domain Specific Language в моей api. Мне бы очень хотелось сделать это, чтобы добавить статический метод в класс через расширение, но я исследовал, что это невозможно с этого сайта. Итак, давайте поговорим о том, что я действительно хочу сделать на примере.Добавление статического метода в класс в C#, я знаю, что вы не можете хотеть альтернативы
Скажите, что у вас есть класс, который служит службой данных (может быть база данных, или отдых или что-то еще).
Класс требует, чтобы вы инициализировали его некоторыми, скажем так, данными о местоположении, чтобы он знал, куда указывать. Эта информация о местоположении не будет известна до времени выполнения.
Обычно вы бы это сделали. , ,
DataService service = new DataService(locationData);
Order = service.getOrderDetails(orderId);
Однако почти во всех случаях, пользователю просто нужно будет задать на вопрос о DataService, а затем двигаться дальше, закройте область действия. Я хотел бы, чтобы какая-то идиома сделала это более дружелюбным для пользователя. Когда я узнал о методах расширения, пожелал сделать это. , ,
Order = DataService.at(location).getOrderDetails(orderId);
Это, конечно, тоже можно, но я хотел бы поставить этот шаблон/идиому на многие классы, которые имеют это понятие места. Я пробовал методы расширения (не могу быть статичным). Я попытался наследовать от GenericClass, что обеспечивает при методе:
public class DSL<T>
where T : new()
{
public T at(Location location)
{
return new T(location);
}
}
вы не можете передать аргументы конструктору для переменного типа :(
Я не люблю делать следующее:
public class DSL<T>
where T : ILocationable, new()
{
public T at(Location location)
{
T result = new T();
result.setLocation(location);
return result;
}
}
, потому что я не люблю классы, которые могут быть созданы и не инициализированы.
Какие альтернативы у вас есть, добавьте этот метод «at» или обеспечить лучшую идиому для обработки этого типа api.
UPDATE:
я придумал механизм, который делает то, что мне нужно:
Сначала я это в файле в моей библиотеке области/инструментов. Файл называется DSL.CS содержание ниже:
namespace R3
{
static public class DSL
{
static public Services.CloudConnection Cloud(string cloud)
{
return Services.CloudFactory.get(cloud);
}
}
}
Когда я объявляю метод, который я хочу использовать это с техникой
static public void fixSequenceError(this CloudConnection cloud, OrderId id)
{
if(inSequenceError(cloud, id))
{
cloud.db.setOrderStatus(id, BLAH);
cloud.db.setOrderItemsStatus(id, BLAHBLAH);
}
}
затем в любом файле я хочу использовать эту идиому в мне нужно сделать что-то в стиле фанк вместо стандарт включает в себя:
using static R3.DSL;
Теперь я могу ввести такие вещи, как:
Cloud(locationData).fixSequenceError
или
Cloud(orderInfo.cloudLocation).db.changeAppOrderStatus
Для эффективности, CloudFactory возвращается статический выделенный объектом, который связан с этим cloudLocation, кажется, много различных синглтон хэшированными с идентификатором. Когда вызывается Cloud(location).foobar(orderId)
Я вызываю foobar, используя объект, специфичный для этого местоположения. Я делаю это без того, чтобы предварять каждое действие с Cloud cloud = CloudFactory.getCloud(location)
Я уверен, что ваш метод должен быть заменен на статический, я думаю, что для универсальных методов экземпляра требуется определение класса, которое можно ввести. –
@ ErikPhilips Нет, они этого не делают. Просто попробовал. Вы можете использовать этот класс, например, DSL dsl = новый DSL(); Заказ заказа = dsl.at (location) .getOrderDetails (orderId); 'Отлично работает. –
Ой, подождите, вы правы, я думал о конструкторах. –