Дженерики в C#, с помощью типа переменной как параметр [дубликат]

Этот вопрос уже имеет ответ здесь:

У меня есть общий метод

bool DoesEntityExist(Guid guid, ITransaction transaction) where T : IGloballyIdentifiable;

Как делают я использую метод следующим образом:

Type t = entity.GetType();
DoesEntityExist(entityGuid, transaction);

Я продолжаю получать следующую ошибку компиляции:

Тип или 't' имени пространства имен не могли быть найдены (Вы пропускаете директиву использования или ссылку на сборку?)

DoesEntityExist(entityGuid, transaction);

работы отлично, но я не хочу использовать если директива для вызова метода с отдельным именем типа каждым разом.

119
задан Germstorm 21 January 2010 в 08:36
поделиться

4 ответа

Точка о дженеранах состоит в том, чтобы дать время компиляции Тип безопасности - это означает, что типы должны быть известны при компиляции времени.

Вы CAN CAN Вызов генерических методов с типами, известными только при время выполнения, но вы должны использовать отражение:

// For non-public methods, you'll need to specify binding flags too
MethodInfo method = GetType().GetMethod("DoesEntityExist")
                             .MakeGenericMethod(new Type[] { t });
method.Invoke(this, new object[] { entityGuid, transaction });

ICK.

Можете ли вы сделать ваш вызовов в соответствии со способом методом универсальным способом, и пройти в параметре вашего типа в качестве аргумента типа типа, нажимая решение об одном уровне более высокого уровня?

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

161
ответ дан 24 November 2019 в 01:50
поделиться

Один из способов обойти это - это использовать неявное литье:

bool DoesEntityExist<T>(T entity, Guid guid, ITransaction transaction) where T : IGloballyIdentifiable;

вызывает это так:

DoesEntityExist(entity, entityGuid, transaction);

Идет на шаг дальше, вы можете включить его в метод расширения (это понадобится быть объявленным в статическом классе):

static bool DoesEntityExist<T>(this T entity, Guid guid, ITransaction transaction) where T : IGloballyIdentifiable;

призывает как так:

entity.DoesEntityExist(entityGuid, transaction);
33
ответ дан 24 November 2019 в 01:50
поделиться

Я не уверен, правильно ли правильно ли вы понимаете ваш вопрос, но вы можете написать свой код таким образом:

Bool DotEtityexist (T экземпляр ...)

Вы можете вызвать метод следующим образом:

DoesEntityExist(myTypeInstance, ...)

Таким образом, вам не нужно явно написать тип, каркас автоматически обожат тип из экземпляра.

7
ответ дан 24 November 2019 в 01:50
поделиться

Вы не можете использовать его так, как вы описываете. Точка о родовых типах, заключается в том, что, хотя вы можете не знать их в «Время кодирования», компилятор должен быть в состоянии разрешить их во время компиляции. Почему? Потому что под капотом компилятор уйдет и создает новый тип (иногда называемый закрытым универсальным типом) для каждого разного использования «открытого» родового типа.

Другими словами, после компиляции

DoesEntityExist<int>

- это другой тип

DoesEntityExist<string>

, вот как компилятор может пополнить безопасность типа компиляции.

Для сценария вы описываете, вы должны пройти тип в качестве аргумента, который можно проверить во время выполнения.

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

4
ответ дан 24 November 2019 в 01:50
поделиться
Другие вопросы по тегам:

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