Как зайти в Даркнет?!
25th January, 01:11
5
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
893
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
912
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4350
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4395
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Статические методы в интерфейсе / абстрактном классе
Во-первых, я понимаю причины, по которым интерфейс или абстрактный класс (в терминологии .NET/C#) не может иметь абстрактных статических методов. Мой вопрос тогда больше сосредоточен на лучшем дизайнерском решении.
Мне нужен набор классов "helper", каждый из которых имеет свои собственные статические методы, так что если я получу объекты A, B и C от стороннего поставщика, у меня могут быть вспомогательные классы с такими методами, как
AHelper.RetrieveByID(string id); AHelper.RetrieveByName(string name); AHelper.DumpToDatabase();
Поскольку мои классы AHelper, BHelper и CHelper в основном будут иметь одни и те же методы, то, по-видимому, имеет смысл переместить эти методы в интерфейс, из которого эти классы затем выводятся. Однако желание, чтобы эти методы были статическими, не позволяет мне иметь универсальный интерфейс или абстрактный класс, из которого все они будут производными.
Я всегда могу сделать эти методы нестатическими, а затем сначала создать экземпляр объектов, таких как
AHelper a = new AHelper(); a.DumpToDatabase();
Однако этот код не кажется мне таким интуитивным. Какие у вас есть предложения? Следует ли мне вообще отказаться от использования интерфейса или абстрактного класса (ситуация, в которой я сейчас нахожусь), или это может быть переработано для выполнения дизайна, который я ищу?
На вашем месте я бы постарался избежать любой статики. ИМХО я всегда заканчивал с какими-то проблемами синхронизации по дороге со статикой. Тем не менее, вы представляете классический пример универсального программирования с использованием шаблонов. Я возьму на вооружение шаблонное решение Rob Copper, представленное в одном из постов выше.
Глядя на ваш ответ я думаю примерно следующее:
- Вы можете просто иметь статический метод, который принимает параметр типа и выполняет ожидаемую логику на основе типа.
- Вы можете создать виртуальный метод в своей абстрактной базе, где вы указываете SQL в конкретном классе. Таким образом, он содержит весь общий код, который требуется для обоих (например, выполнение команды и возврат объекта) при инкапсуляции битов "specialist" (например, SQL) в подклассах.
Я предпочитаю второй вариант, хотя он, конечно, зависит от вас. Если вам нужно, чтобы я углубился в дальнейшие детали, пожалуйста, дайте мне знать, и я буду рад редактировать / обновлять :)
Я лично, возможно, задался бы вопросом, почему каждый из типов должен иметь статический метод, прежде чем даже думать дальше..
Почему бы не создать класс utlity со статическими методами, которые они должны совместно использовать? (например, ClassHelper.RetrieveByID(string id) или ClassHelper<ClassA>.RetrieveByID(string id)
В моем опыте работы с такого рода "roadblocks" проблема заключается не в ограничениях языка, а в ограничениях моего дизайна..
Вы не можете перегружать методы, изменяя только тип возвращаемого значения.
Вы можете использовать разные имена:
static AObject GetAObject(string id);
static BObject GetBObject(string id);
Или вы можете создать класс с операторами приведения:
class AOrBObject
{
string id;
AOrBObject(string id) {this.id = id;}
static public AOrBObject RetrieveByID(string id)
{
return new AOrBObject(id);
}
public static AObject explicit operator(AOrBObject ab)
{
return AObjectQuery(ab.id);
}
public static BObject explicit operator(AOrBObject ab)
{
return BObjectQuery(ab.id);
}
}
Тогда вы можете назвать это так:
var a = (AObject) AOrBObject.RetrieveByID(5);
var b = (BObject) AOrBObject.RetrieveByID(5);
В C# 3.0 статические методы могут использоваться на интерфейсах, как если бы они были частью их, используя методы расширения, как в DumpToDatabase() ниже:
static class HelperMethods
{ //IHelper h = new HeleperA();
//h.DumpToDatabase()
public static void DumpToDatabase(this IHelper helper) { /* ... */ }
//IHelper h = a.RetrieveByID(5)
public static IHelper RetrieveByID(this ObjectA a, int id)
{
return new HelperA(a.GetByID(id));
}
//Ihelper h = b.RetrieveByID(5)
public static IHelper RetrieveByID(this ObjectB b, int id)
{
return new HelperB(b.GetById(id.ToString()));
}
}
Как разместить отзыв о переполнении стека? Отредактируйте мою оригинальную запись или опубликуйте "answer"? Во всяком случае, я подумал, что это может помочь привести пример того, что происходит в AHelper.RetrieveByID() и BHelper.RetreiveByID() годах
В принципе, оба этих метода идут против стороннего веб-сервиса, который возвращает различные универсальные (кастабельные) объекты, используя метод запроса, который принимает в качестве единственных параметров строку псевдо-SQL.
Итак, AHelper.RetrieveByID(string ID) может выглядеть следующим образом
public static AObject RetrieveByID(string ID)
{
QueryResult qr = webservice.query("SELECT Id,Name FROM AObject WHERE Id = '" + ID + "'");
return (AObject)qr.records[0];
}
public static BObject RetrieveByID(string ID)
{
QueryResult qr = webservice.query("SELECT Id,Name,Company FROM BObject WHERE Id = '" + ID + "'");
return (BObject)qr.records[0];
}
Надеюсь, это поможет. Как вы можете видеть, эти два метода похожи, но запрос может быть довольно сильно отличаться в зависимости от возвращаемого типа объекта.
О, и Роб, я полностью согласен - это скорее всего ограничение моего дизайна, а не языка. :)
Вы ищете полиморфное поведение? Тогда вам понадобится интерфейс и обычный конструктор. Что такого неинтуитивного в вызове конструктора? Если вам не нужен полиморфизм (похоже, вы его сейчас не используете), то вы можете придерживаться своих статических методов. Если все это обертки вокруг компонента поставщика, то, возможно, вы можете попробовать использовать фабричный метод для их создания, например VendorBuilder.GetVendorThing("A"), который может возвращать объект типа IVendorWrapper.
марксидад просто быстрый момент, чтобы отметить, Джастин уже сказал, что SQL сильно меняется в зависимости от типа, поэтому я работал на основе того, что это может быть что-то совершенно другое, зависящее от типа, следовательно, делегируя его в рассматриваемые подклассы. Тогда как ваше решение очень тесно связывает SQL с типом (т. е. это SQL).
rptony хорошая точка зрения на возможные проблемы синхронизации со статикой, которую я не упомянул, так что спасибо:) Кроме того, его Роб Купер (не медь) BTW ;): D (EDIT : просто подумал, что я упомяну, что в случае, если это не опечатка , я ожидаю, что это так, так что никаких проблем!)