я могу сделать это
private static void Execute<T>(IList<T> points, ...) where T : Point2D
{
if (typeof(T) == typeof(Point3D)) // Point3D only
{
но я хотел бы проверить Point3D
и все производные типы, например:
private static void Execute<T>(IList<T> points, ...) where T : Point2D
{
if (T is Point3D) // Point3D ans derived types
{
но я получаю: Ошибка CS0119: "T" - это тип, который недействителен в данном контексте
Point3D
класс наследуется от Point2D
одного.
Есть ли способ сделать это?
Вы уверены, что все, что вы делаете, является хорошей идеей? Point3D
/ Point2D
в большинстве случаев должны быть структурными, чтобы улучшить использование памяти и локальность, поскольку точек, вероятно, много. Использование производных типов противоречит этой цели, и, возможно, point3D не является point2D, но может иметь такие свойства, как XY
для преобразования в Point2D. Использование интерфейсов в качестве общих ограничений может быть уместным, но тогда вы должны использовать интерфейс и избегать явных проверок типов.
typeof(Point3D).IsAssignableFrom(typeof(T))
Вы можете использовать один из Type.IsAssignableTo
/Type.IsAssignableFrom
:
IsAssignableTo
— Определяет, может ли текущий тип быть присвоен переменной указанного targetType.
IsAssignableFrom
— Определяет, может ли экземпляр указанного типа c быть присвоен переменной текущего типа.
if (typeof(T).IsAssignableTo(typeof(Point3D)))
Обратите внимание, что IsAssignableTo
был введен в .NET 5, поэтому для более ранней версии фреймворка вам нужно использовать «обратное»:
if (typeof(Point3D).IsAssignableFrom(typeof(T)))
Если у меня есть Point4D
, который наследуется от Point3D
, вернет ли он true?
@abenci да, так как Point3D x = new Point4D()
является допустимым утверждением.
Я получаю эту ошибку, этот метод специфичен для какой-либо версии языка С#? Ошибка CS1061: «Тип» не содержит определения для «IsAssignableTo», и не удалось найти доступный метод расширения «IsAssignableTo», принимающий первый аргумент типа «Тип» (вам не хватает директивы использования или ссылки на сборку?)
@abenci Этот метод был добавлен в .NET 5.
@abenci используйте «обратное» if (typeof(Point3D).IsAssignableFrom(typeof(T)))
private static void Execute<T>(IList<T> points, ...) where T : Point3D
Вам не подошло?