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
tostring
) - A reference conversion within a type hierarchy (e.g. casting
object
tostring
)
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
Piping in a File on the Command-Line Using System.Diagnostics.Process
Error "This Stream Does Not Support Seek Operations" in C#
ASP.NET C# Static Variables Are Global
How to Segment the Elements Iterated Over in a Foreach Loop
Unity 5.5 Obsolete Particle System Code
Set Item Focus in Listview Wpf
Entity Framework Db-First, Implement Inheritance
Directoryinfo.Enumeratefiles(...) Causes Unauthorizedaccessexception (And Other Exceptions)
Excluding Some Properties During Serialization Without Changing the Original Class
C#: Cast to Generic Interface with Base Type
Creating a Database Programmatically in SQL Server
How to Apply Indenting Serialization Only to Some Properties
Taking Screenshot of a Webpage Programmatically
Datagrid Column Width Doesn't Auto-Update