Transcript Document

C#
Structs, operator overloading &
attributes
Structs ~ Structures
• Structs are similar to classes: they
represent data structures with data and
functions.
• Structs are different from classes:
variables of a struct type directly contain
the value, whereas variables of a class
type contain a reference to the value
(i.e. the object).
Structs 2
• Structs are value types and are said to
have value semantics.
struct Point {
public int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
Structs 3
• Classes are reference types and are
said to have reference semantics.
Point a = new Point(10, 10);
Point b = a;
a.x = 100;
System.Console.WriteLine(b.x);
• Point is a struct: 10; Point is a class:
100
Constructing structs
• All struct types implicitly inherit directly from
System.ValueType, and are never
abstract.
• A struct is not permitted to declare a
parameterless instance constructor; every
struct has one implicitly.
• The default value of a struct is the value
produced by setting all its value type fields to
their default value and all its reference type
fields to null.
• The struct value itself cannot be null.
Operators & operands
• Expressions are constructed from
operands and operators.
• The operators of an expression indicate
which operations to apply to the
operands.
• Examples of operators include + , - , * , /
, and ‘new’.
• Examples of operands include literals,
fields, local variables, and expressions.
Operators
• Three kinds of operators:
– Unary operators. The unary operators take one
operand and use either prefix notation (such as –x
) or postfix notation (such as x++ ).
– Binary operators. The binary operators take two
operands and all use infix notation (such as x + y
).
– Ternary operator. Only one ternary operator, ?: ,
exists; it takes three operands and uses infix
notation
(c ? x : y ).
Operator overloading 1
• Certain operators can be overloaded.
(Cannot overload e.g. = , && , || , ?:,
method invocation or member access)
• Operator overloading permits userdefined operator implementations to be
specified for operations
Operator overloading 2
• User-defined operator declarations
always require at least one of the
parameters to be of the class or struct
type that contains the operator
declaration.
• User-defined operator declarations
cannot modify the syntax, precedence,
or associativity of an operator.
Operator overloading example
using System;
public struct Digit {
byte value;
public Digit(byte value) { this.value = value; }
public Digit(int value): this((byte) value) {}
public static Digit operator+(Digit a, Digit b) {
return new Digit(a.value + b.value);
}
public static Digit operator-(Digit a, Digit b) {
return new Digit(a.value - b.value);
}
public static bool operator==(Digit a, Digit b) {
return a.value == b.value;
}
…
}
Attributes
• C# programmers can attach attributes to
various program entities, and retrieve
attribute information at run-time.
• Principally analogous to well-known
declarations of program entities, e.g. method
access: public, protected, and private.
• Attributes are accessible at run-time in a
“reflective” manner.
Attributes 2
• A class that derives from the abstract
class System.Attribute is an
attribute class.
• The declaration of an attribute class
defines a new kind of attribute that can
be placed on a declaration.
• By convention, attribute classes are
named with a suffix of ‘Attribute’.
Attribute parameters
• Attribute classes can have positional
parameters and named parameters.
• Each public instance constructor for an
attribute class defines a valid sequence
of positional parameters for that
attribute class.
• Each non-static public read-write field
and property for an attribute class
defines a named parameter for the
attribute class.
Attribute example
using System;
[AttributeUsage(AttributeTargets.Class)]
public class HelpAttribute: Attribute {
public HelpAttribute(string url) { // url is a positional
parameter
}
public string Topic { // Topic is a named parameter
get {…}
set {…}
}
public string Url { get {…} }
}
Attribute example (cont.)
This Help attribute class might be used as follows:
[Help("http://www.mycompany.com/…/Class1.htm")]
class Class1 {
…
}
[Help("http://www.mycompany.com/…/Misc.htm", Topic ="Class2")] 1
class Class2 {
…
}
Querying attributes
using System;
class Test {
static void Main() {
Type type = typeof(Class1);
object[] arr = type.GetCustomAttributes(typeof(HelpAttribute), true);
if (arr.Length == 0)
Console.WriteLine("Class1 has no Help attribute.");
else {
HelpAttribute ha = (HelpAttribute) arr[0];
Console.WriteLine("Url = {0}, Topic = {1}", ha.Url, ha.Topic);
}
}
}
Using System;
class Test {
static void Main() {
string s = "Test";
string t = string.Copy(s);
Console.WriteLine(s == t);
Console.WriteLine((object)s == (object)t);
}
}
Produces:
True
False
Design goals
• Simple, modern, general-purpose, objectoriented programming language.
• Software robustness, durability, and
programmer productivity are important.
• Not intended to compete directly on
performance and size with C or assembly
language.
Hello, World
• Source stored in one or more text files with
a file extension of .cs
using System;
class Hello {
static void Main() {
Console.WriteLine("hello, world");
}
}
• compiled with a command line like
csc hello.cs
Language details
• C# is a standard proposal from ECMA Technical
Committee 39, Task Group 2 (TG2)
• C# does not contain a standard class library
• Common Language Infrastructure (CLI) is a
standard for a library and execution environment
• CLI is a standard proposal from Task Group 3
Unified type system
using System;
class Test {
static void Main() {
Console.WriteLine(3.ToString());
}
}
Boxing/unboxing
• ” This type system unification provides value
types with the benefits of object-ness without
introducing unnecessary overhead.”
class Test {
static void Main() {
int i = 123;
object o = i; // boxing
int j = (int) o; // unboxing
}
}
Casting
• Implicit casting
• Explicit casting
Example of reference passing
using System;
class Test {
static void Swap(ref int a, ref int b) {
int t = a;
a = b;
b = t;
}
static void Main() {
int x = 1;
int y = 2;
Console.WriteLine("pre: x = {0}, y = {1}", x, y);
Swap(ref x, ref y);
Console.WriteLine("post: x = {0}, y = {1}", x, y);
}
}
Produces:
pre: x = 1, y = 2
post: x = 2, y = 1 2
Parameters
•
•
•
•
Value parameter
Reference parameter
Output parameter
Parameter array
Value parameters
• Used for ’in’ passing to a method
• Value is copied to method’s scope
Example of value passing
using System;
class Test {
static void F(int p) {
Console.WriteLine("p = {0}", p);
p++;
}
static void Main() {
int a = 1;
Console.WriteLine("pre: a = {0}", a);
F(a);
Console.WriteLine("post: a = {0}", a);
}
}
Produces:
pre: a = 1
p = 1
post: a = 1
Example of output parameters
using System;
class Test {
static void Divide(int a, int b, out int result, out int remainder) {
result = a / b;
remainder = a % b;
}
static void Main() {
for (int i = 1; i < 10; i++)
for (int j = 1; j < 10; j++) {
int ans, r; 18
Divide(i, j, out ans, out r);
Console.WriteLine("{0} / {1} = {2}r{3}", i, j, ans, r);
}
}
}
Properties & Indices
Delegates