windows and web apps in c# david figge [email protected] [email protected] session 5 last update: 4/11page...
Post on 19-Dec-2015
215 views
TRANSCRIPT
Copyright (C) 2010 by David Figge. All Rights Reserved.
Windows and Web Apps in C#
David [email protected]
Session 5
Last Update: 4/11 Page 1
Copyright (C) 2010 by David Figge. All Rights Reserved.
Checkbook Register
Let’s take a look at my solution for the Checkbook Register program…
Last Update: 4/11 Page 2
Copyright (C) 2010 by David Figge. All Rights Reserved.
Session 5
Playing with the Web Interfaces Generics
Last Update: 4/11 Page 3
Copyright (C) 2010 by David Figge. All Rights Reserved.
Windows and Web Apps in C#
Playing with the Web
Last Update: 4/11 Page 4
Copyright (C) 2010 by David Figge. All Rights Reserved.
Web Interface
As we’ve discussed, all that you’ve been learning applies to any UI environment you choose – it’s all C#
To demonstrate this, let’s take our Checkbook program’s data and display it on a Web page Although we’ll just display the database
data, you can easily port your existing classes over and provide more detail to the page…
Last Update: 4/11 Page 5
Copyright (C) 2010 by David Figge. All Rights Reserved.
Movin’ to the Web
Last Update: 4/11
To begin with, we’ll work together Then you’ll have a chance to work on your own
for a while… Together let’s
Create a new ASP Web Page Open the Data Connection (in Server Explorer)
and drag the Transactions table onto the page Try running the app. In one simple step, we’ll got a
GridView connected to our Transaction table displaying its data. Hard to get easier than that!!!
Press the arrow to display the properties, and choose “Enable Editing”. You can now edit the entries as well!
Page 6
Copyright (C) 2010 by David Figge. All Rights Reserved.
Your Turn
Last Update: 4/11
Using the data techniques we just learned: Add 6 labels to the page. Enter text into three
(“Account Name: ”, “Account Number: “, and “Initial Balance: “). Name the other 3 so you can initialize their values. Make sure they’re laid out in a logical manner
In the page constructor Create a SqlConnection to the database, read in
the first Account record (“SELECT * FROM Account”), then populate the 3 labels with the account name, number, and initial balance.
Be sure to close all connections and readers.
Page 7
30 Minutes
Copyright (C) 2010 by David Figge. All Rights Reserved.
Windows and Web Apps in C#
Interfaces
Last Update: 4/11 Page 8
Interfaces
As we start talking about Interfaces, some obvious questions come up:
What is an interface? Why should I use interfaces?
You can think of an interface as sort of a “job contract”. In C#, this contract promises that certain functions and
properties will exist in your object. Let’s look at a real-life parallel, then we’ll look at a
programming example.
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 9
Interfaces
Imagine you’re working for a software company, and you want are creating an accounting program. You would probably come up with a job description asking for:
C# development skills Accounting skills SQL Development skills
These skills describe how you’re going to interact with this new developer...what this developer must be able to do
In C#, this ‘way we’re going to interact’ – the contract if you will -- is called an interface
Not making too much sense yet? Let’s try again from a programming perspective…
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 10
Interfaces
Let’s say I’m writing a Windows program that allows objects to be manipulated on the screen. Every object on the screen has to have the ability to:
Be selectable (highlight it on the window) Be moveable (to a new location on the window) Be copied (copy it to the clipboard) Be pasted (pasted from the clipboard) Be deleted (delete it from the window)
So, as a developer, I define an interface that enforces these requirements, thus ensuring that any object that wants to be placed onto the screen must have the above functionality.
So an interface is an agreement between a user of an class and the class that specific functionality will be there.
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 11
Interfaces
So, in C# an interface defines a set of methods and properties that must be included by any class that implements the interface So, in the example above, a class would
have methods to Select the object Move the object Copy the object Paste the object Delete the object
The interface describes (via a prototype) what methods must be implemented
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 12
Interfaces
So why an interface, can’t you do this with inheritance?
In some cases, yes you could. But you would limit yourself: You would have to derive from the interface
You couldn’t have a window object derived from another class (C# doesn’t allow multiple inheritance)
All classes within the class hierarchy would support being placed on the window
All classes would have to implement the ‘place on a window’ functions (even if it didn’t make sense for them)
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 13
Interfaces
So, interfaces allows A separate hierarchy to exist apart from the
class hierarchy Only objects that should be placed on the
screen (apart from other objects in the class hierarchy) need implement the interface.
So one class in a hierarchy might implement the interface, but another might not
The window manipulation function has a consistent way to deal with all objects on the screen, regardless of where they came from
Classes can implement multiple interfacesLast Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 14
Interfaces
Let’s look at another example that might help solidify this concept (sort of a bit more conceptual)
Let’s say we have an interface called Squeezable
Think about what objects would fit into that interface
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 15
Interfaces
Objects to consider Fruit possibilities
Lemon: Squeezable Orange: Squeezable Watermelon: Not squeezable
Containers Plastic Bottles: Squeezable Glass Bottles: Not Squeezable
Balls Tennis Ball: Squeezable Billiard Ball: Not squeezable
As you can see, whether or not they’re squeezable may not pertain to their base class
Let’s see how we can use these…
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 16
Code
Example Interfaces
interface Squeezable { int SqzDepth(); }... // Definition of other classesSqueezable[] sq = new Squeezable[3];sq[0] = new Orange();sq[1] = new Lemon();sq[2] = new PlasticBottle();
foreach (Squeezable s in sq) {Console.WriteLine(“Squeeze depth {0}”, s.SqzDepth());}
Here’s the definition of our Squeezable interface
Here’s the definition of our Squeezable interface
The definition has only one function in it: return the depth to which you can squeeze the object.
The definition has only one function in it: return the depth to which you can squeeze the object.
Here we’re creating a new array of squeezable objects. Interface names can be used as a data type. Only items that implement the interface can be in this array, but any one that does, can be included (regardless of it’s object type)
Here we’re creating a new array of squeezable objects. Interface names can be used as a data type. Only items that implement the interface can be in this array, but any one that does, can be included (regardless of it’s object type)
Here I add 3 items to the array.Here I add 3 items to the array.
Finally, here I’m using the SqzDepth function within the interface. Note that, because s is type Squeezable, I can only refer to methods within the interface (as they’re the only ones I can know exist in each element)
Finally, here I’m using the SqzDepth function within the interface. Note that, because s is type Squeezable, I can only refer to methods within the interface (as they’re the only ones I can know exist in each element)
Making senseso far?
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 17
Interfaces
So, let’s look a bit more at Interface definitions Except for the multiple inheritance
issues, you can think of interfaces as abstract classes where all the members are abstract.
Interfaces cannot contain any fields(variables) but they can contain properties.
Let’s see our example in code…
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 18
Code
Example Interface Example
interface IWindowObject{ void Select(); // Select the object void Move(int x, int y); // Move to new coordinates void Copy(); // Copy to clipboard void Paste(int x, int y); // Paste from clipboard void Delete(); // Delete the object int x { get; set; } // Example of properties
int y { get; set; }}
Remember, none of the functions or properties has any body to it. They look like abstract classes with no function definitions.
Remember, none of the functions or properties has any body to it. They look like abstract classes with no function definitions.
Interface methods are inherently public, and must be public in the class that implements the interface.
Interface methods are inherently public, and must be public in the class that implements the interface.
Questions so far?
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 19
Interfaces
So, when we create a class, how do we declare that we implement the interface?
You reference the interface just like you reference the base class…
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 20
Code
Example Interface Example
class Picture : IWindowObject{
public void Select() { ... }public void Move(int x, int y) { ... }public void Copy() { ... }public void Paste(int x, int y) { ... }public void Delete() { ... }public int x {
get { ... }set { ... } }
public int y {get { ... }set { ... }
... // Other functions implemented by class
}
The syntax for implementing an interface is like deriving from a base class.
The syntax for implementing an interface is like deriving from a base class.
You can derive from as many interfaces as you need to. Just list them all separated by commas.
You can derive from as many interfaces as you need to. Just list them all separated by commas.
After declaring that you implement the interface, of course, you have to provide the implementation.
After declaring that you implement the interface, of course, you have to provide the implementation.
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 21
Explicit Implementation
So, what do you do if you want to implement an interface with a Select() method, but you already have a Select() method? Well, if the Select() method can meet the
needs of the new interface, you can just use it. If the existing method doesn’t meet the needs
of the new interface, you can use explicit naming for the new method, like
void IWindowObject.Select() { ... } This is the method that will be used for the
IWindowObject interface objects (and is only accessible via an IWindowObject object).
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 22
Inheritance Issues
When a base class implements an interface, because it includes all the methods of the interface (and you inherit them), you also inherit the interface.
So, if you inherit from a class that can be put on a window (IWindowObject), you can also be put on a window.
Obviously, you want to be careful overriding or replacing any methods that are used in interfaces. Ready to give
this a try?
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 23
Implementing Foreach
Using the foreach loop is convenient The syntax is simple It knows how to get data from a collection
and how many there are It would be nice if we could get this C#
feature to work with our own classes Well, we can, and in this exercise we will
make the foreach loop work with our BankAccount class Which manages the collection of Transactions But first, let’s look more at the interfaces
involved…
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 24
Copyright (C) 2010 by David Figge. All Rights Reserved.
The Foreach Interfaces
The developers of the foreach construct recognized that there were 3 pieces to navigating through a collection, and put them into an interface so any collection can support foreach!
To make foreach work with your collection class, you have to implement two interfaces
IEnumerator – applies to classes that have data that you can identify and move through one at a time
IEnumerable – identifies an object that you interact with to navigate through that collection
Let’s look at these before we start playing…
Last Update: 4/11 Page 25
Copyright (C) 2010 by David Figge. All Rights Reserved.
Code
Example The IEnumerator Interface
public interface IEnumerator{
object Current { get; }
bool MoveNext();
void Reset();}
Last Update: 4/11 Page 26
The IEnumerable interface consists of
3 elements (one property and two
functions)
To go through the items in a collection, you start at the
beginning, then move one by one until you reach the end.The Current property retrieves the
‘current’ item that you are working with.
Note that Current implements only the get portion. The implementing class
can choose to have a set, but it is not required for the interface.
The Reset() function is used to reset the ‘current record’ to 1 before the first record, so that the series
of “move...retrieve…move…retrieve” can start. Interestingly, Reset is never called by the system. You
should call Reset() yourself as you prepare the foreach to start (more on this in a minute).
The MoveNext() function moves the ‘current record’ to the next record in line. If it moved
to a valid record, you return True. If you moved past the end of the records, you
return False (which exits the foreach loop)
Is this making sense?
So, to process a foreach statement, it becomes
while (MoveNext returns True){ Retrieve Current Process it in the foreach loop}
Copyright (C) 2010 by David Figge. All Rights Reserved.
Code
Example The IEnumerable Interface
Public interface IEnumerable{ IEnumerator GetEnumerator();}
Last Update: 4/11 Page 27
IEnumerable identifies objects that support enumeration. This interface has only one element: GetEnumerator. GetEnumerator returns an object that manages the enumeration process (that is, the foreach loop process).
To provide the most flexibility and support as many simultaneous loops running at the same time, the object returned from this function would be one created by the
collection class, with the sole purpose of supporting enumeration. A much simpler design is for the collection
object itself to provide for the enumeration, but that almost always means only one enumeration can be going
at a time.
The BankAccount Class
So we’re going to implement the IEnumerator and IEnumerable interfaces within our BankAccount class
This will enable it to work with foreach Each of these functions will do the following:
IEnumerable: Reset() – Move our counter variable to -1 MoveNext() – If our counter variable is referencing our last
record, return false. Otherwise, increment our counter variable and return true
Current { get; } – return the transaction associated with the counter variable
IEnumerator: GetEnumerator() – Return the current object, which will
manage the enumeration process Ready to give it a go?
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 28
Copyright (C) 2010 by David Figge. All Rights Reserved.
Implementing Foreach
Last Update: 4/11
We’ll work together to Implement IEnumerable and IEnumerator
in our BankAccount class Add int current to the class Add Reset (current = -1) Add MoveNext (moves current until =
NumTrans) Add Current.Get ( returns
transactions[current]) Add GetEnumerator (return this)
Swap out or for() loop for a foreach()
Page 29
Interface Notes
When you implement an interface, you are implementing a public interface, and are thus creating an “Is A” relationship
Implementing an interface implicitly allows the user to get to the methods via an object instance of the implementing class.
Implementing an interface explicitly (e.g. IEnumerable.Current) requires the use of an interface variable.
Only an IEnumerator reference can see explicitly defined methods.
One interface can be derived from another. The derived interface can choose to hide a method declared in the base interface using the new keyword (similar to class inheritance).
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 30
The IDisposable Interface
Who remembes the Dispose() method? It’s the method called automatically at the end of a
using statement Wll, this method is actually an
implementation of the IDisposable interface. This is the only method in this interface.
By implementing IDisposable interface you too can also use the using keyword.
This is recommended when you have elements that must be returned, recycled, or somehow closed when a process completes.
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 31
Interface Summary
An interface is a contract. Once created and used, it should not
change. Doing so would break classes that use it
If you need to change the interface, you should create a whole new interface, perhaps derived from the old one.
Classes can only inherit from one class. Classes can implement multiple interfaces.
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 32
Interface Summary
Abstract classes should be used primarily for objects that are closely related, whereas interfaces are best suited for providing common functionality to unrelated classes.
Abstract class: a Shape class that is inherited by other RELATED shaped-based classes.
Interface: IDisposable that declares a Dispose() method where multiple UNRELATED classes can implement this method.
Abstract classes allow you to partially implement your base class (allowing derived classes to reuse the implementation), whereas interfaces contain no implementation for any members.
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 33
Copyright (C) 2010 by David Figge. All Rights Reserved.
Questions?
Are there any questions on interfaces?
Last Update: 4/11 Page 34
Copyright (C) 2010 by David Figge. All Rights Reserved.
Windows and Web Apps in C#
Introduction to Generics
Last Update: 4/11 Page 35
Copyright (C) 2010 by David Figge. All Rights Reserved.
The Issues with Generic Collections
When .Net 1.0 was released it contained a group of collection classes
Classes designed to hold and organize data… Issue: In order to store “anything”, they were
designed to hold any derivative of “Object” Problems:
This is largely inefficient, as value types end up being boxed and unboxed, creating lots of extra objects and overhead
There was no way to force the collection to hold only certain types of classes (only Cars…)
So you had lots of overhead to verify data types before taking actions on them
Thus, with .Net 2.0, Generics were introduced.
Last Update: 4/11 Page 36
Collection Class Description
ArrayList A dynamically sized collection of objects in sequential order
Hashtable A collection of key/value pairs organized based on the hash code of the key
Queue A first-in, first-out (FIFO) queue
SortedList A collection of key/value pairs sorted by keys and accessible via key or index
Stack A last-in, first-out (LIFO) stack with Push/Pop (and peek) functionality
Introduction To Generics
So what are generics for? Without generics, we can’t make type-
safe AND well-performing collections. To use C#’s built-in type safety
Type safety allows potential errors to be trapped by the compiler (reliably), rather than to be found at run time (unreliably).
When you assign data to that variable, the compiler checks to see if the assignment is valid and notifies you if there is a problem.
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 37
Generics
The solution to all of the type safety problems we’ve discussed is to create type-specific collections. As we’ve seen, though, we can’t reuse the code easily.
A generic collection is a collection that allows you to define type-safe classes without compromising performance or productivity.
Generic classes are defined with a special syntax that allows one class to support any data type
The syntax also allows the class to specify constraints upon the target data type, thus ensuring a compatible data type from the start.
You can recognize a generic class because it is declared using angle brackets: List<T>
T is the traditional placeholder for “data type”Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 38
Copyright (C) 2010 by David Figge. All Rights Reserved.
An example
A Linked List is a collection of objects that are connected together in order
Typically, a global variable (Head) points to the start of the list. There may also be a “Tail” variable.
Each element has a reference to the next element in line
Thus, you can navigate from “Head” through the list to find a specific record
Last Update: 4/11 Page 39
Head Tail
null5 16 12 7 22
Referenceto Next
Copyright (C) 2010 by David Figge. All Rights Reserved.
An Example
The problem with the List object is: If I’ve defined a list of “Person” objects (all with a Next reference). What if I insert a non-Person data type that doesn’t have a “next” reference? An exception gets triggered, and I need to
figure out how to recover. The solution is solved by using
List<Person>. The compiler gives a compile error if
anything other than a Person object is added to the list
Last Update: 4/11 Page 40
Copyright (C) 2010 by David Figge. All Rights Reserved.
Code
Example List<T> Class Declaration
public class List<T>{ public void Add(T item) {...} public int BinarySearch(T item) {...} public bool Contains(T item) {...} public void CopyTo(T[] item) {...} public T[] ToArray() {...} public bool Remove(T item) {...} public T this[int index] { get {...}; set {...};} ...}
Last Update: 4/11 Page 41
This is an example of the List<T> class as it is created in source
code. However, when you instantiate it as List<Person>,
you can think of it as transforming into…
Copyright (C) 2010 by David Figge. All Rights Reserved.
Code
Example List<Person> Class Declaration
public class List<Person>{ public void Add(Person item) {...} public int BinarySearch(Person item) {...} public bool Contains(Person item) {...} public void CopyTo(Person[] item) {...} public Person[] ToArray() {...} public bool Remove(Person item) {...} public Person this[int index] {get {...}; set {...};} ...}
Last Update: 4/11 Page 42
…this. A List class specifically built for use with Person objects. The
compiler creates as specialized version for whomever requests it.
This allows us to have the improved efficiency and type checking.
Copyright (C) 2010 by David Figge. All Rights Reserved.
Using Generics
Last Update: 4/11
We’re going to work together to swap out our Transaction[] array and replace it with a List<Transaction> Swap out the variable Modify the insertion to use .Add Make NumTrans property return
the .Count property of the List object. Note that, since List supports index access,
the methods we added to support foreach still work.
Page 43
Copyright (C) 2010 by David Figge. All Rights Reserved.
Code
Example An Example Function
static void Swap(ref Person p1, ref Person p2){
Person temp;temp = p1; // Save current P1p1 = p2; // Swap P2P2 = temp; // Swap P1
}
Last Update: 4/11 Page 44
You are welcome to write you own generic functions! The easiest place to start is with a working function. This example swaps two
references (on exit, P1 and P2 have swapped objects).
Now identify those places where you would like the data type to adapt to something else. It’s okay to keep variables of other types as needed (ints for counting, etc.)
Copyright (C) 2010 by David Figge. All Rights Reserved.
Code
Example An Example Function
static void Swap<T>(ref T p1, ref T p2){
T temp;temp = p1; // Save current P1p1 = p2; // Swap P2P2 = temp; // Swap P1
}
Last Update: 4/11 Page 45
Now, just insert a <T> after the Swap function name, then replace the Person references to T (the adapting data type place-holder). You could now call this
function with Swap<int>(ref 3, ref 4) or Swap<String>(ref s1, ref s2).
Of course, you can go a long ways with this, including generic classes with data
constraints. See the book for more on programming using generics.
Notes: Generics and Inheritance
When deriving from a generic base class, you must provide an actual type rather than the base class’ generic type placeholder:public class BaseClass<T>{ …}
public class SubClass : BaseClass<int>{ …}
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 46
Notes: Generics and Inheritance
A base class can define virtual methods whose signatures use generic type placeholders. When overriding them, the derived class must provide actual types in the method signatures:public class BaseClass<T> { public virtual T SomeMethod() { … }}
public class SubClass : BaseClass<int> { public override int SomeMethod() { … }}
Last Update: 4/11 Copyright (C) 2010 by David Figge. All Rights Reserved.Page 47
Copyright (C) 2010 by David Figge. All Rights Reserved.
Questions
Questions on Generics?
Last Update: 4/11 Page 48
Copyright (C) 2010 by David Figge. All Rights Reserved.
Windows and Web Apps in C#
End of Session 5
Last Update: 4/11 Page 49