Как узнать, что конкретный Type ссылочный?
От: alexzzzz  
Дата: 14.01.20 17:30
Оценка:
Вопрос праздный, возник случайно.

1. Что нужно написать вместо ???, чтобы для ссылочных типов ответ был True?

using System;

class Program
{
    static void Main()
    {
        Print(typeof(int));
        Print(typeof(int*));
        Print(typeof(int[]));
    }

    static void Print(Type type)
    {
        Console.WriteLine($"{type.Name} is a value-type: {type.IsValueType}");
        Console.WriteLine($"{type.Name} is a pointer-type: {type.IsPointer}");
        Console.WriteLine($"{type.Name} is a reference-type: {type.???}"); // <----- ???
        Console.WriteLine();
    }
}


Можно конечно перебором. По спецификации, к ссылочным типам относятся массивы, делегаты, интерфейсы и классы (в том числе string, object и dynamic). Если что-то из этого, то тип ссылочный. Но вдруг в C# 12 добавят что-то ещё ссылочное.

Можно методом исключения: если не value-тип и не указатель, значит ссылочный тип. Но вдруг в C# 13 появится четвёртый, доселе неизвестный тип типов.

2. Что такое Type.IsByRef ?

Справка говорит как-то расплывчато. Непонятно, что это означает:

Gets a value indicating whether the Type is passed by reference.

Remarks
To get to the actual type, dereference the type that was passed by reference, and then call GetElementType on that type.


Там даже есть пример кода, из которого вроде кажется, что IsByRef как раз должен возвращать true для ссылочных типов. Но он так не работает: для массивов и для классов возвращает false.
Отредактировано 14.01.2020 17:33 alexzzzz . Предыдущая версия .
Re: Как узнать, что конкретный Type ссылочный?
От: romangr Россия  
Дата: 14.01.20 18:12
Оценка: 4 (1)
Здравствуйте, alexzzzz, Вы писали:

A>2. Что такое Type.IsByRef ?


class Program
{
    static void Main()
    {
        var type = typeof(Program).GetMethod("Method").GetParameters()[0].ParameterType;
        Print(type);
    }

    static void Print(Type type)
    {
        Console.WriteLine($"{type.Name} is a byref-type: {type.IsByRef}");
        Console.WriteLine();
    }

    public void Method(ref int value)
    {
    }
}
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Re: Как узнать, что конкретный Type ссылочный?
От: TK Лес кывт.рф
Дата: 14.01.20 22:12
Оценка:
Здравствуйте, alexzzzz, Вы писали:

A>Вопрос праздный, возник случайно.


кошмар какой

A>Можно методом исключения: если не value-тип и не указатель, значит ссылочный тип. Но вдруг в C# 13 появится четвёртый, доселе неизвестный тип типов.


Посылочный. Но, вам его не отдадут т.к credentials нету — такие типы можно смело игнорировать.

A>2. Что такое Type.IsByRef ?


A>Справка говорит как-то расплывчато. Непонятно, что это означает:

A>

Gets a value indicating whether the Type is passed by reference.


A>Там даже есть пример кода, из которого вроде кажется, что IsByRef как раз должен возвращать true для ссылочных типов. Но он так не работает: для массивов и для классов возвращает false.


Справка описывает ситуацию буквально. Очевидно, что переменные типа Array, object, int и т.п. в обычных сценариях передаются по значению (если конечно понимать, что на самом деле хранится в переменной).

Потому и получается, что не смотря на то, что оно как-бы класс, но IsByRef там false
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[2]: Как узнать, что конкретный Type ссылочный?
От: alexzzzz  
Дата: 15.01.20 12:36
Оценка:
Здравствуйте, TK, Вы писали:

TK>вам его не отдадут т.к credentials нету — такие типы можно смело игнорировать.

В смысле?
Re: Как узнать, что конкретный Type ссылочный?
От: _NN_ www.nemerleweb.com
Дата: 15.01.20 19:58
Оценка:
Здравствуйте, alexzzzz, Вы писали:

IsClass

Gets a value indicating whether the Type is a class or a delegate; that is, not a value type or interface.


Подойдёт ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Как узнать, что конкретный Type ссылочный?
От: alexzzzz  
Дата: 15.01.20 20:59
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Подойдёт ?


Чёрт его знает, какая у него логика:
Console.WriteLine(typeof(int*).IsClass); // печатает True
Re: Как узнать, что конкретный Type ссылочный?
От: Sinclair Россия https://github.com/evilguest/
Дата: 16.01.20 03:24
Оценка:
Здравствуйте, alexzzzz, Вы писали:

A>Можно методом исключения: если не value-тип и не указатель, значит ссылочный тип.

Да, это наиболее надёжный способ. Спецификация CLR описывает ровно три вида типов: ссылочные, значения, и указатели.
A>Но вдруг в C# 13 появится четвёртый, доселе неизвестный тип типов.
Тогда вашу программу придётся переписать.
Но лучше задаться вопросом "а зачем мне это надо?". Скорее всего, окажется, что для решения настоящей задачи не потребуется никакого IsReferenceType(Type type).
Например, для забоксенного инта GetType().IsValueType выдаёт true, а на самом деле значение ссылочное.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Как узнать, что конкретный Type ссылочный?
От: alexzzzz  
Дата: 17.01.20 07:11
Оценка:
Здравствуйте, Sinclair, Вы писали:

A>>Можно методом исключения: если не value-тип и не указатель, значит ссылочный тип.

S>Да, это наиболее надёжный способ. Спецификация CLR описывает ровно три вида типов: ссылочные, значения, и указатели.

В ECMA-335 минимум в одном месте pointer types и function pointer types перечислены через запятую.
Re[3]: Как узнать, что конкретный Type ссылочный?
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.01.20 11:33
Оценка:
Здравствуйте, alexzzzz, Вы писали:
A>В ECMA-335 минимум в одном месте pointer types и function pointer types перечислены через запятую.
Ну, мест может быть много. Вот то, которое нас интересует:

There are two kinds of types: value types and reference types.

Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Как узнать, что конкретный Type ссылочный?
От: alexzzzz  
Дата: 17.01.20 12:10
Оценка:
Здравствуйте, Sinclair, Вы писали:

В общем, из всего следует вывод, что у CLI, C# и System.Reflection — у каждого собственная отличающаяся точка зрения на классификацию типов. Ждать строгости и логичности не стоит.
Отредактировано 17.01.2020 12:14 alexzzzz . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.