#c# #generics #reflection
#c# #дженерики #отражение
Вопрос:
Объясненный ниже во фрагменте кода, я не могу понять синтаксис для этого:
object tcsObject = new TaskCompletionSource<Apple>();
Apple apple = new Apple();
// How do I do this?
TaskCompletionSource<apple.GetType>() tsc = tscObject as TaskCompletionSource<apple.GetType>()
Редактировать
Следует отметить, что конкретная проблема, которую я пытаюсь решить, заключается в том, как выполнить это приведение дженериков, изначально не зная, что тип — это Apple. Тип может в конечном итоге быть любым, поэтому я хочу выполнить эту операцию из того, что возвращается через GetType .
Комментарии:
1. Вы можете использовать отражение, но проблема в том, что весь дальнейший код, который будет его использовать, также должен использовать отражение. Не лучше ли было бы замаскировать это под
TaskCompletionSource<object>
?2. Вы не можете передавать динамические типы в обобщенные. Дженерики — это концепция времени компиляции, GetType выполняется во время выполнения
3. Вы не можете. Компилятору необходимо знать тип каждой переменной во время компиляции . Либо с известным фиксированным типом, либо с вашим собственным параметром универсального типа в области видимости.
4. В этом примере тип всегда
Apple
так почему бы вам просто не использоватьTaskCompletionSource<Apple>
?5. Вы могли бы создать метод со всем кодом в нем, который должен использовать
TaskCompletionSource<T>
, а затем использовать отражение для вызова этого метода, тогда вы, по крайней мере, минимизировали бы количество необходимых отражений.
Ответ №1:
Если вы не возражаете пожертвовать безопасностью типов во время компиляции, вы могли бы использовать Convert.ChangeType()
dynamic
ключевое слово and следующим образом:
static dynamic ConvertTo(this object source, Type targetType)
{
return (dynamic)Convert.ChangeType(source, targetType)
}
public void YourActualCode()
{
object tcsObject = new TaskCompletionSource<Apple>();
Apple apple = new Apple();
TaskCompletionSource<Apple> tsc = ConvertTo(tscObject, typeof(TaskCompletionSource<Apple>))
}
Самое приятное в этом подходе то, что вы можете отложить определение типа параметра до времени выполнения:
var wrapperType = typeof(TaskCompletionSource<>);
var paramType = typeof(Apple);
var concreteType = wrapperType.MakeGenericType(paramType);
TaskCompletionSource<Apple> tsc = ConvertTo(tscObject, concreteType);
Комментарии:
1. Спасибо вам за это. То, что я действительно пытался выяснить, это как создать универсальный тип из GetType. В частности, яблоко. GetType. Поскольку проблема, с которой я борюсь, заключается в том, что я не знаю, каким типом может оказаться Apple.
2. @rygo6 тогда вы определенно хотите что-то вроде
typeof(TaskCompletionSource<>).MakeGenericType(apple.GetType())
🙂