honey the codewitch Ответов: 3

Как я могу увидеть, является ли экземпляр кортежем?


if (val.GetType().FullName.StartsWith("System.Tuple`"))
	System.Diagnostics.Debugger.Break();


Это работает, но это сомнительно. Я ищу что-то, связанное с определением универсального типа, например, с typeof(Tuple<>), Но это не работает.

Мне все равно, сколько аргументов у Кортежа. Мне просто нужно знать, так ли это.

Что я уже пробовал:

if (val.GetType().FullName.StartsWith("System.Tuple`"))
	System.Diagnostics.Debugger.Break();


Это работает, но довольно хитро. Я хочу, чтобы это сломалось на typeof(Tuple< & gt;) или аналогичном.

3 Ответов

Рейтинг:
24

Richard Deeming

Если вы используете .NET 4.7.1 или более позднюю версию, вы можете проверить, реализует ли она Система.Время Выполнения.Услуги компиляторов.ITuple интерфейс[^]:

if (value is System.Runtime.CompilerServices.ITuple)
Это также позволит обнаружить новое ValueTuple<> типы.

В противном случае вам нужно будет получить определение универсального типа и сравнить его с восемью открытыми Tuple<> универсальные типы, поскольку они не имеют общего базового класса.
private static readonly HashSet<Type> TupleTypes = new HashSet<Type>
{
    typeof(Tuple<>),
    typeof(Tuple<,>),
    typeof(Tuple<,,>),
    typeof(Tuple<,,,>),
    typeof(Tuple<,,,,>),
    typeof(Tuple<,,,,,>),
    typeof(Tuple<,,,,,,>),
    typeof(Tuple<,,,,,,,>),
};

public static bool IsTuple(Type type) => type != null
    && type.IsGenericType 
    && TupleTypes.Contains(type.GetGenericTypeDefinition());

public static bool IsTuple(object value) => value != null 
    && IsTuple(value.GetType());
Вот этот не будет включите в себя ValueTuple<> типы, если вы не добавите их в список.


honey the codewitch

Вот оно, волшебство, на которое я надеялся! re: ITuple

Afzaal Ahmad Zeeshan

5ед.

BillWoodruff

+5

BillWoodruff

Тест "foo is ValueType" кажется допустимым для любого экземпляра ValueTuple с любым количеством параметров. Конечно, я использую фреймворк более поздней версии.

Может ли существовать Кортеж< gt;: Я знаю, что не могу объявить его в VStudio, так же как я не могу объявить ValueTuple без хотя бы одного экземпляра юридического типа,

honey the codewitch

ну да, я думаю, что это тип значения в том смысле, что он происходит от ValueType, а не непосредственно от object, но это не совсем то, что я ищу, так как int также возвращает true там тоже.

вы не можете объявить частичные дженерики, но вы можете вызвать typeof на них так, как typeof(IList<>) работает, но класс foo : IList<> {} не работает

я думаю, что ValueTuple просто использует ref внутренне (это тип ref) или что-то в этом роде. я должен проверить

BillWoodruff

Тип ' ValueTuple-это представление типа значения кортежа."

Экземпляры этого типа являются изменяемыми и являются структурами. Если вы используете "именованные аргументы", то эти метаданные не сериализуемы.

Это новая структура, начиная с C#7, .NET FrameWork >= 4.

Я предлагаю вам изучить его определение и использование:

https://stackoverflow.com/a/41084470

https://blogs.msdn.microsoft.com/mazhou/2017/05/26/c-7-series-part-1-value-tuples/

Рейтинг:
2

#realJSOP

Это не работает?

if (val is Tuple)


OriginalGriff

Опубликовано в качестве решения:
- я почти уверен, что пытался это сделать, но у меня ничего не вышло. Мои кортежи, которые я использую в качестве тестового набора, имеют два аргумента. Это может иметь какое - то отношение к делу. Я также попробовал typeof(Tuple< gt;) На жаворонке. Я не могу сделать typeof(Tuple<,>), потому что я не знаю, сколько аргументов будут иметь кортежи заранее."
кодовый переключатель медовый кризис

honey the codewitch

я почти уверен, что пытался это сделать, но у меня ничего не вышло. Мои кортежи, которые я использую в качестве тестового набора, имеют два аргумента. Это может иметь какое - то отношение к делу. Я также попробовал typeof(Tuple< gt;) На жаворонке. Я не могу сделать typeof(Tuple<,>), потому что я не знаю, сколько аргументов будут иметь кортежи заранее. Я попробую Кортеж еще раз просто чтобы быть уверенным и исправить свой ответ если я ошибаюсь

Рейтинг:
16

phil.o

С Tuple у вас есть много определений, каждое из которых имеет разное количество общих аргументов, и я не думаю, что существует волшебное решение (кроме того, которое вы используете), чтобы получить, является ли экземпляр кортежем или нет. Проблема typeof(Tuple<>) будет только совпадать Tuple<T1>, одноэлементный вариант.


honey the codewitch

Я так и думал, но Ричард Демминг внизу нашел магию, которую я искал. Требуется .NET 4.71, но это нормально.

Afzaal Ahmad Zeeshan

5ед.