Дженерики C# и проверка типа

Я справляюсь с этой проблемой, создавая класс DatabaseManager, который обрабатывает маловероятное событие, когда царство выдает ошибку:

public class DatabaseManager {

    static var realm: Realm {
        get {
            do {
                let realm = try Realm()
                return realm
            }
            catch {
                NSLog("Could not access database: ", error)
            }
            return self.realm
        }
    }

    public static func write(realm: Realm, writeClosure: () -> ()) {
        do {
            try realm.write {
                writeClosure()
            }
        } catch {
            NSLog("Could not write to database: ", error)
        }
    }
}

Благодаря этому решению код выглядит намного чище, когда я хочу читать из области или писать в db:)

DatabaseManager.write(realm: realm) {
    let queryResult = self.realm.objects(Cookies.self).filter("cookieId == %@", cookieId)
    let cookie = queryResult.first
    cookie?.expirationDate = expirationDate as NSDate?
}
71
задан J0e3gan 19 September 2014 в 21:52
поделиться

7 ответов

Вы можете использовать перегрузки:

public static string BuildClause(List<string> l){...}

public static string BuildClause(List<int> l){...}

public static string BuildClause<T>(List<T> l){...}

Или вы можете проверить тип общего параметра:

Type listType = typeof(T);
if(listType == typeof(int)){...}
104
ответ дан 24 November 2019 в 13:00
поделиться

Вы можете использовать typeof (T) .

private static string BuildClause<T>(IList<T> clause)
{
     Type itemType = typeof(T);
     if(itemType == typeof(int) || itemType == typeof(decimal))
    ...
}
19
ответ дан 24 November 2019 в 13:00
поделиться

Вы можете использовать typeOf (T) , но я бы дважды проверил ваш метод и убедился, что вы не нарушаете единую ответственность. Это будет запах кода, и это не значит, что этого не следует делать, но вы должны быть осторожны.

Суть дженериков заключается в том, чтобы создавать алгоритмы, не зависящие от типа, если вам все равно, что это за тип, или пока он соответствует определенному набору критериев. Ваша реализация не очень универсальна.

1
ответ дан 24 November 2019 в 13:00
поделиться

Ваша конструкция полностью противоречит цели универсального метода. Это уродливо нарочно, потому что должен быть лучший способ достичь того, чего вы пытаетесь достичь, хотя вы не предоставили нам достаточно информации, чтобы понять, что это такое.

2
ответ дан 24 November 2019 в 13:00
поделиться

Оператор typeof ...

typeof(T)

... не будет работать с оператором switch в C #. Но как насчет этого? В следующем сообщении содержится статический класс ...

Есть ли лучшая альтернатива, чем эта, для «включения типа»?

... которая позволит вам написать такой код:

TypeSwitch.Do(
    sender,
    TypeSwitch.Case<Button>(() => textBox1.Text = "Hit a Button"),
    TypeSwitch.Case<CheckBox>(x => textBox1.Text = "Checkbox is " + x.Checked),
    TypeSwitch.Default(() => textBox1.Text = "Not sure what is hovered over"));
4
ответ дан 24 November 2019 в 13:00
поделиться

По умолчанию знаю, что нет лучшего способа. Некоторое время назад я разочаровался в этом и написал небольшой служебный класс, который немного помог и сделал синтаксис немного чище. По сути, он превращает код в

TypeSwitcher.Do(clause[0],
  TypeSwitch.Case<int>(x => ...),  // x is an int
  TypeSwitch.Case<decimal>(d => ...), // d is a decimal 
  TypeSwitch.Case<string>(s => ...)); // s is a string

Полная запись в блоге, а подробности о реализации доступны здесь

6
ответ дан 24 November 2019 в 13:00
поделиться

Невозможно использовать оператор switch для того, что вы хотите. Оператор switch должен поставляться с целыми типами, которые не включают сложные типы, такие как объект «Тип», или любой другой тип объекта в этом отношении.

2
ответ дан 24 November 2019 в 13:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: