VB vs С# - CType vs ChangeType

Почему это работает в VB.Net:

Dim ClipboardStream As New StreamReader(
    CType(ClipboardData.GetData(DataFormats.CommaSeparatedValue), Stream))

Но это вызывает ошибку в С#:

Поток - это тип, который недействителен в текущем контексте

ClipboardStream = new StreamReader(Convert.ChangeType(
    ClipboardData.GetData(DataFormats.CommaSeparatedValue), Stream));

Честно говоря, я не на 100% сомневался в конвертировании типов, я использовал их только в фрагментах кода, и теперь я пытаюсь преобразовать простой фрагмент кода VB в версию С#...

Ответ 1

ChangeType принимает Type как второй параметр, поэтому вы должны написать typeof(Stream). typeof(Stream) вычисляет экземпляр Type представляющий тип Stream. Просто использование Stream не работает, потому что оно не оценивает значение. Это не выражение.

В любом случае, вы все равно не должны использовать ChangeType, вы должны использовать его, что эквивалентно С# для CType:

 ClipboardStream = new StreamReader((Stream)ClipboardData.GetData(DataFormats.CommaSeparatedValue));

Ответ 2

CType - это функция компилятора в VB.Net. Он позволяет второму аргументу быть выражением, которое дает имя типа. Вы не можете самостоятельно записывать такие функции в VB или С#.

С# с использованием Convert будет, как говорит Патрик, быть:

ClipboardStream = new StreamReader(Convert.ChangeType(
ClipboardData.GetData(DataFormats.CommaSeparatedValue),typeof(Stream)));

Но этот код ближе к тому, если бы это было написано в VB:

ClipboardStream = New StreamReader(Convert.ChangeType( _
ClipboardData.GetData(DataFormats.CommaSeparatedValue),GetType(Stream)))

CType в VB намного ближе к листингу в С# (например, (Stream)... вместо CType(..., Stream))

Ответ 3

Потому что передача типа в С# отличается от того, что он находится в VB.NET. Вы должны использовать typeof(Stream):

ClipboardStream = new StreamReader
                    ( Convert.ChangeType
                        ( ClipboardData.GetData(DataFormats.CommaSeparatedValue)
                        , typeof(Stream)
                        )
                    );

В этом случае, однако, простой бросок был бы лучше:

ClipboardStream = new StreamReader
                    ( (Stream)ClipboardData.GetData(DataFormats.CommaSeparatedValue)
                    );

Ответ 4

Convert.ChangeType ожидает аргумент Type во втором параметре. Чтобы получить экземпляр Type из переменной, вызовите метод GetType() или используйте оператор typeof:

ClipboardStream = new StreamReader(Convert.ChangeType(
ClipboardData.GetData(DataFormats.CommaSeparatedValue), Stream.GetType()));


ClipboardStream = new StreamReader(Convert.ChangeType(
ClipboardData.GetData(DataFormats.CommaSeparatedValue), typeof(Stream)));

Другим способом (предпочтительным способом) является использование оператора литья

ClipboardStream = new StreamReader((Stream)ClipboardData.GetData(DataFormats.CommaSeparatedValue));