jamheadart
jamheadart

Reputation: 5303

VB vs C# — CType vs ChangeType

Why does this work in VB.Net:

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

But this is throwing an error in C#:

Stream is a Type, which is not valid in the current context

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

To be honest, I'm not 100% clued up on converting types, I've only ever used them in code snippets and now I'm trying to convert a simple VB code snippet to a C# version...

Upvotes: 13

Views: 1591

Answers (4)

Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239646

CType is a compiler function in VB.Net. It allows its second argument to be an expression that yields a type name. You cannot write functions like that yourself in either VB or C#.

The C# using Convert would be, as Patrick says, be:

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

But this code is closer to if this had been written in VB:

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

CType in VB is a lot closer to a cast in C# (e.g. (Stream)... rather than CType(..., Stream))

Upvotes: 8

Sweeper
Sweeper

Reputation: 270890

ChangeType accepts a Type as the second parameter, so you should write typeof(Stream). typeof(Stream) evaluates to a Type instance representing the type Stream. Just using Stream there does not work because it does not evaluate to a value. It's not an expression.

Anyway, you shouldn't be using ChangeType here anyway, you should cast, which is the C# equivalent of CType:

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

Upvotes: 14

adjan
adjan

Reputation: 13652

Convert.ChangeType expects a Type argument in its second parameter. To obtain the Type instance from a variable, call the GetType() method or use the typeof operator:

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


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

Another way (imo the preferred way) is to use the casting operator

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

Upvotes: 5

Patrick Hofman
Patrick Hofman

Reputation: 156938

Because passing in a type in C# is different than it is in VB.NET. You should use typeof(Stream):

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

In this case however, a simple cast would be better:

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

Upvotes: 7

Related Questions