Typecasting in C#

Typecasting in C#

Casting is usually a matter of telling the compiler that although it only knows that a value is of some general type, you know it's actually of a more specific type. For example:

object x = "hello";

...

// I know that x really refers to a string
string y = (string) x;

There are various conversion operators. The (typename) expression form can do three different things:

  • An unboxing conversion (e.g. from a boxed integer to int)
  • A user-defined conversion (e.g. casting XAttribute to string)
  • A reference conversion within a type hierarchy (e.g. casting object to string)

All of these may fail at execution time, in which case an exception will be thrown.

The as operator, on the other hand, never throws an exception - instead, the result of the conversion is null if it fails:

object x = new object();
string y = x as string; // Now y is null because x isn't a string

It can be used for unboxing to a nullable value type:

object x = 10; // Boxed int
float? y = x as float?; // Now y has a null value because x isn't a boxed float

There are also implicit conversions, e.g. from int to long:

int x = 10;
long y = x; // Implicit conversion

Does that cover everything you were interested in?

Which is the best practice in C# for type casting?

At least there are two possibilities for casting, one for type checking and a combination of both called pattern matching. Each has its own purpose and it depends on the situation:

Hard cast

var myObject = (MyType)source;

You normally do that if you are absolutely sure if the given object is of that type. A situation where you use it, if you subscribed to an event handler and you cast the sender object to the correct type to work on that.

private void OnButtonClick(object sender, EventArgs e)
{
var button = (Button)sender;

button.Text = "Disabled";
button.Enabled = false;
}

Soft cast

var myObject = source as MyType;

if (myObject != null)
// Do Something

This will normally be used if you can't know if you really got this kind of type. So simply try to cast it and if it is not possible, simply give a null back. A common example would be if you have to do something only if some interface is fullfilled:

var disposable = source as IDisposable;

if(disposable != null)
disposable.Dispose();

Also the as operator can't be used on a struct. This is simply because the operator wants to return a null in case the cast fails and a struct can never be null.

Type check

var isMyType = source is MyType;

This is rarely correctly used. This type check is only useful if you only need to know if something is of a specific type, but you don't have to use that object.

if(source is MyType)
DoSomething();
else
DoSomethingElse();

Pattern matching

if (source is MyType myType)
DoSomething(myType);

Pattern matching is the latest feature within the dotnet framework that is relevant to casts. But you can also handle more complicated cases by using the switch statement and the when clause:

switch (source)
{
case SpecialType s when s.SpecialValue > 5
DoSomething(s);
case AnotherType a when a.Foo == "Hello"
SomethingElse(a);
}

C# how to avoid typecasting to subclass?

You can use generics for this, even without reflection. This sample uses the parameterless constructor filter on T (sample altered from Adil):

public T GetShape<T>() where T : Shape, new()
{
return new T();
}

type casting in c#.net

When it comes to boxing and unboxing, types have explicit and implicit casting. So, in some circumstances, it is easy enough for the runtime to allow for implicit conversion between two supported types, say an Int32 to a Double. However, there is no implicit or explicit conversion between an integer and a string, because obviously, a string is not an integer (despite the fact that a string can contain characters for an integer).

string s = i; // attempt at implicit cast from Int32 to String, error
object o = i; // all types inherit from Object, so you may implicitly or explicitly cast from Int32 to Object.
s = (string)i; // attempt at explicit cast from Int32 to string, error
s = i.ToString(); // conversion
s = Convert.ToString(i); // conversion

That's where Convert comes to play. Convert contains support for attempting to convert known primitives (and types supporting IConvertable) to another. So, ToString or Convert.ToString would be the preferred methods (ToString and Convert.ToString are virtually synonymous, except that ToString gives you some formatting options).

What does C# do when typecasting a letter to an int?

You're converting a char to int. A char is a UTF-16 code unit - an unsigned 16-bit integer (the range is [0, 65535]). You get that value, basically, widened to a 32-bit signed integer. So 'A' ends up as 65, for example, and the Euro symbol (U+20AC) ends up as 8364 (0x20ac).

As for your second part - you're creating an int, you're creating an int array. An yes, you'll be creating an array with 320 elements.

Typecasting to a Base Class

It means you don't need to explicitly cast the derived object to the base type.

DerivedClass derived1 = new DerivedClass();

// This is an implicit coversion:
BaseClass base1 = derived1;

// This is an explicit conversion:
DerivedClass derived2 = (DerivedClass) base1;

Regardless of how you convert, you can't call a method defined in a derived class from a variable of the base type. To call a method from a derived type, you'd need to explicitly cast to that type:

((DerivedClass) base1).derived_name();

System.convert.ToString() vs Explicit typecasting in c#

In answer to the first part of your question: Casting and Converting are two different things.
I'm not a Java developer, but I would suspect it's the same in Java.

MSDN has an article which answers this in detail: Casting and Type Conversions (C# Programming Guide)

Type Conversion in C#

I still doubt your performance claims. Here's evidence. Compile and run the program below (in release mode):

using System;
using System.Diagnostics;

class Test
{
const int Iterations = 100000000;

static void Main()
{
Stopwatch sw = Stopwatch.StartNew();
decimal d = 1.0m;
long total = 0;
for (int i=0; i < Iterations; i++)
{
long x = ConvertTo<long>(d);
total += x;
}
sw.Stop();
Console.WriteLine("Time: {0}ms", sw.ElapsedMilliseconds);
Console.WriteLine("Total: {0}", total);
}

public static T ConvertTo<T>(object data) where T : struct
{
return (T) Convert.ChangeType(data, typeof(T));
}
}

That takes 20 seconds on my laptop - to execute 100,000,000 iterations. It's hard to believe that it takes 8 seconds on your computer to execute 40 iterations.

In other words, I strongly suspect that the problem isn't where you think it is.



Related Topics



Leave a reply



Submit