You are on page 1of 45

Operators and Type Safety

Prepared By:
Esha Batish
Lecture No-28
Date-02-05-2011
Operators in C#
• Operators are used to manipulate data.
• Although most of C# ’ s operators familiar to
C and C++.The operators supported by C# are:
• Arithmetic +–*/%
• Logical &|^ ~ && || !
• String concatenation +
• Increment and decrement ++ ––
• Bit shifting << >>
• Comparison == != < > <= >=
• Assignment = += -= *= /= %= &= |= ^= <<=
>>=
• Member access (for objects and structs) .
• Indexing (for arrays and indexers) []
• Cast ()
• Conditional (the ternary operator) ?:
• Delegate
• Object creation new
• Type information sizeof, is, typeof, as
• Overflow exception control checked
unchecked
• Indirection and address []
• Namespace alias qualifier
• ::
• Null coalescing operator ??
Note that four specific operators (sizeof, *, ->,
and &, however, are available only in unsafe
code (code that bypasses C#’s type-safety
checking).
Shortcut Operator Equivalent To
• x++, ++x x = x + 1
• x--, --x x = x – 1
• x += y x = x + y
• x -= y x = x - y
• x *= y x = x * y
• x /= y x = x / y
• x %= y x = x % y
• x >>= y x = x >> y
• x <<= y x = x << y
• x &= y x = x & y
• x |= y x = x | y
checked and unchecked operators
• If you mark a block of code as checked, the
CLR will enforce overflow checking, and
throw an OverflowException if an overflow
occurs.
• Consider the following code:
byte b = 255;
b++;
Console.WriteLine(b.ToString());
Contd..
• The byte data type can hold values only in the
range 0 to 255, so incrementing the value of b
causes an overflow. So its good to use
checked.
• byte b = 255;
• checked
• {
• b++;
• }
• Console.WriteLine(b.ToString());
• When you try to run this code, you will get an
error message like this:Unhandled Exception:
System.OverflowException:Arithmetic operation
resulted in an overflow at
Wrox.ProCSharp.Basics.OverflowTest.Main(Strin
g[] args)
• If you want to suppress overflow checking, you
can mark the code as unchecked. In this case, no
exception will be raised, but you will lose data
— because the byte type cannot hold a value of
256, the overflowing bits will be discarded, and
your b variable will hold a value of zero (0).
• byte b = 255;
• unchecked
• {
• b++;
• }
• Console.WriteLine(b.ToString());

Note that unchecked is the default behavior.


The is operator
• The is operator allows you to check whether
an object is compatible with a specific type.
The phrase“ is compatible ” means that an
object either is of that type or is derived from
that type. For example, to check whether a
variable is compatible with the object type,
you could use the following bit of code:
• int i = 10;
• if (i is object)
• {
• Console.WriteLine("i is an object");
• }
• int , like all C# data types, inherits from object
,therefore, the expression i is object will
evaluate to true in this case.
The as operator
• The as operator is used to perform explicit type
conversions of reference types. If the type being
converted is compatible with the specified type,
conversion is performed successfully. However,
if the types are incompatible, the as operator
returns the value null .
• object o1 = "Some String";
• object o2 = 5;
• string s1 = o1 as string; // s1 = "Some String"
• string s2 = o2 as string; // s2 = null
• The as operator allows you to perform a safe
type conversion in a single step without the
need to first test the type using the is operator
and then perform the conversion.
• The sizeof operator:
• You can determine the size (in bytes) using
the sizeof operator:
• Console.WriteLine(sizeof(int));
• This will display the number 4 , because an
int is 4 bytes long. If you are using the sizeof
operator with complex types (and not
primitive types), you will need to block the
code within an unsafe block as illustrated
here:
• unsafe
• {
• Console.WriteLine(sizeof(Customer));
• }
The typeof operator
• The typeof operator returns a System.Type
object representing a specified type.
• For example,typeof(string) will return a Type
object representing the System.String type.
This is useful when you want to find out
information about an object dynamically.
Nullable Types and Operators
• Looking at the Boolean type, you have only a
true or false value that you can assign to this
type. However, what if you wanted to define
the value of the type as undefined?
• int? a = null;
• int? b = a + 4; // b = null
• int? c = a * 5; // c = null
• However, when comparing nullable types, if
only one of the operands is null , the
comparison will always equate to false .
• int? a = null;
• int? b = -5;
• if (a > = b)
• Console.WriteLine("a > = b");
• else
• Console.WriteLine("a < b");
• The possibility of a null value means that you
cannot freely combine nullable and non-
nullable types in an expression.
Nullable Types’s Characteristics
• Nullable types represent value-type variables
that can be assigned the value of null. You
cannot create a nullable type based on a
reference type. (Reference types already
support the null value.)
• The syntax T? is shorthand for
System.Nullable<T>, where T is a value type.
• Assign a value to a nullable type in the same
way as for an ordinary value type, for
example int? x = 10; or double? d = 4.108;
• Use the System.Nullable.GetValueOrDefault
property to return either the assigned value, or
the default value for the underlying type if the
value is null, for example int j =
x.GetValueOrDefault();
• Use the HasValue and Value read-only properties
to test for null and retrieve the value.
• The HasValue property returns true if the
variable contains a value, or false if it is null.
• The Value property returns a value if one is
assigned, otherwise a
System.InvalidOperationException is thrown.
• The default value for a nullable type variable
sets HasValue to false. The Value is undefined.
• Nested nullable types are not allowed.
class NullableExample
{
static void Main()
{
int? num = null;
if (num.HasValue == true)
{
Console.WriteLine("num = " + num.Value);
}
else
• {
Console.WriteLine("num = Null");
}
//y is set to zero

int y = num.GetValueOrDefault();

// num.Value throws
//InvalidOperationException if num.HasValue
is //false
• try
{
y = num.Value;
}
catch (System.InvalidOperationException e)
{
Console.WriteLine(e.Message);
}
}
}
Here is the output

• num = Null
• Nullable object must have a value.
The null Coalescing operator
• The null coalescing operator ( ?? ) provides a
shorthand mechanism to cater to the possibility
of null values when working with nullable and
reference types. The operator is placed between
two operands — the first operand must be a
nullable type or reference type, and the second
operand must be of the same type as the first or
of a type that is implicitly convertible to the
type of the first operand. The null coalescing
operator evaluates as follows:
• If the first operand is not null , then the
overall expression has the value of the first
operand.
• If the first operand is null , then the overall
expression has the value of the second
operand.
• int? a = null;
• int b;
• b = a ?? 10; // b has the value 10
• a = 3;
• b = a ?? 10; // b has the value 3
• If the second operand cannot be implicitly
converted to the type of the first operand, a
compile - time error is generated.
Operator Precedence
• Group Operators
• Primary () . [] x++ x-- new typeof sizeof
checked unchecked
• Unary + — ! ~ ++x --x and casts
• Multiplication * / %
/division
• Addition +-
• /subtraction
• Bitwise shift operators << >>
• Relational < ><= >= is as
• Comparison == !=
• Bitwise AND &
• Bitwise XOR ^
• Bitwise OR |
• Boolean AND &&
• Boolean OR ||
• Conditional operator ?:
• Assignment = += -= *= /= %= &= |= ^= <<= >>=
>>>=
• In
Type Safety
• The Intermediate Language (IL) enforces
strong type safety upon its code. Strong typing
enables many of the services provided by
.NET, including security and language
interoperability. As you would expect from a
language compiled into IL, C# is also strongly
typed. Among other things, this means that
data types are not always seamlessly
interchangeable. Type Safety looks at
conversions between primitive types.
Type Conversions
• Often, you need to convert data from one type
to another. Consider the following code:
• byte value1 = 10;
• byte value2 = 23;
• byte total;
• total = value1 + value2;
• Console.WriteLine(total);
• When you attempt to compile these lines, you
get the following error message: Cannot
implicitly convert type ‘ int ’ to ‘ byte'
• The problem here is that when you add 2
bytes together, the result will be returned as
an int , not as another byte . This is because a
byte can contain only 8 bits of data, so adding
2 bytes together could very easily result in a
value that cannot be stored in a single byte . If
you do want to store this result in a byte
variable, you are going to have to convert it
back to a byte . The following sections discuss
two conversion mechanisms supported by C#
— implicit and explicit.
Implicit Conversions
• Conversion between types can normally be
achieved automatically (implicitly) only if you
can guarantee that the value is not changed in
any way. This is why the previous code failed; by
attempting a conversion from an int to a byte.
• byte value1 = 10;
• byte value2 = 23;
• long total; // this will compile fine
• total = value1 + value2;
• Console.WriteLine(total);
• The following table shows the implicit type
conversions supported in C#:
• From To
• Sbyte- short, int, long, float, double, decimal
• byte - short, ushort, int, uint long,
ulong,float, double, decimal
• Short- int, long, float, double, decimal
• Ushort- int, uint, long, ulong, float, double,
decimal
• Int- long, float double, decimal
• uint - long, ulong, float, double,
decimal
• Long- ulong float, double, decimal
• float - double
• Char- ushort, int, uint, long, ulong,
float, double, decimal,
Explicit Conversion
• Many conversions cannot be implicitly made
between types, and the compiler will give you
an error if any are attempted. These are some
of the conversions that cannot be made
implicitly:
• int to short — Data loss is possible.
• int to uint — Data loss is possible.
• uint to int — Data loss is possible.
• float to int — You will lose everything after
the decimal point.
• Any numeric type to char — Data loss is
possible.
• decimal to any numeric type — The decimal
type is internally structured differently from
both integers and floating-point numbers.
• int? to int — The nullable type may have the
value null.
• However, you can explicitly carry out such
conversions using casts.
• A cast looks like this:
long val = 30000;
int i = (int)val; // A valid cast.
• You indicate the type to which you are casting
by placing its name in parentheses before the
value to be converted.
• Casting can be a dangerous operation to
undertake. Even a simple cast from a long to
an int can cause problems if the value of the
original long is greater than the maximum
value of an int:
• Using casts, you can convert most primitive
data types from one type to another; for
example.
• double price = 25.30;
• int P = (int)(price + 0.5);
• Output will be 25.
In another code:
• ushort c = 43;
• char symbol = (char)c;
• Console.WriteLine(symbol);
• Output will be ‘+’.
• long val = 3000000000;
• int i = (int)val; // An invalid cast. The
maximum int is 2147483647
• No error will be generated but gives
unpredictable output.
• Another alternative is :
• long val = 3000000000;
• int i = checked((int)val);
• You can convert an array element of type
double to a struct member variable of type int.
• struct ItemDetails
• {
• public string Description;
• public int ApproxPrice;
• }
• double[] Prices = { 25.30, 26.20, 27.40, 30.00 };
• ItemDetails id;
• id.Description = “Hello there.”;
• id.ApproxPrice = (int)(Prices[0] + 0.5);
• To convert a nullable type to a non-nullable
type or another nullable type where data loss
may occur, you must use an explicit cast.for
example, int? to int or float? to float. This is
because the nullable type may have the value
null, which cannot be represented by the non-
nullable type.
• An explicit cast between two equivalent non-
nullable types is possible, However, when
casting from a nullable to non-nullable type
and the variable has the value null, an
InvalidOperationException is thrown.
• int? a = null;
• int b = (int)a; // Will throw exception
• If you need to convert between numeric and
string, you can use methods provided in the
.NET class library.The Object class implements
a ToString() method:
• int i = 10;
• string s = i.ToString();
• Similarly, if you need to parse a string to
retrieve a numeric or Boolean value, you can
use the Parse() method.
• This method is supported by all the
predefined value types:
• string s = “100”;
• int i = int.Parse(s);
• Console.WriteLine(i + 50);
• Note that Parse() will register an error by
throwing an exception if it is unable to
convert the string.
Thank You !

You might also like