Search

Categories

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Send mail to the author(s) E-mail

# Thursday, December 24, 2009

Symbolic constants vs Enumerated Types'

These constants are handy when cheking on the setter (as can use an int range)

    public const int APARTMENT = 1;
    public const int COMMERCIAL = 2;
    public const int HOME = 3;
 
    public int BuildingType
    {
        get { return buildingType; }
        set
        {
            if (value >= APARTMENT && value <= HOME)
                buildingType = value;
        }
    }
This keyword
public clsBuilding()
    {
        address = "Not closed yet";
    }
 
    public clsBuilding(string addr, decimal price, decimal payment, decimal tax, decimal insur, DateTime date, int type)
        : this() // good practise to call initial constructor first..second constructor will overwrite address = "Not closed yet"
    {
        if (addr.Equals("") == false)
            address = addr;
        purchasePrice = price;
        monthlyPayment = payment;
        taxes = tax;
        insurance = insur;
        datePurchased = date;
        buildingType = type;
    }
Base keyword
    public clsCommercial(string addr, decimal price, decimal payment,
                        decimal tax, decimal insur, DateTime date, int type) :
                        base(addr, price, payment, tax, insur, date, type)
    {
        buildingType = type;   // Commercial type from base
    }

this is calling the bases’ constructor.

can also call base methods from the derived (child) class.

Polymorphism

essentially this means we can send the same message to a group of different classes and each class will know how to respond correctly. eg

image

        lstMessages.Items.Add(myApt.RemoveSnow());
        lstMessages.Items.Add(myComm.RemoveSnow());
        lstMessages.Items.Add(myHome.RemoveSnow());

clsApt and clsComm have overridden methods and respond with different phone numbers.  clsHome doesn’t have a RemoveSnow method and responds as above.

Abstract Classes

To prevent instantiation of the base class ie if it makes no sense.

public abstract class clsDeciduous
{
 
Virtual and Override
The method may be overridden in a derived class.
 
    public virtual string RemoveSnow()
    {
        return whichType[buildingType] + ": No snow removal service available.";
    }

And in the derived class:

public override string RemoveSnow()
    {
        return "Commercial: Call Acme Snow Plowing: 803.234.5566";
    }

To prevent further inheritence use public sealed class.

Comments [0] | | # 

From msdn.

        // i is compiled as an int
        var i = 5;
 
        // s is compiled as a string
        var s = "Hello";
 
        // a is compiled as int[]
        var a = new[] { 0, 1, 2 };
 
        // person is compiled as an anonymous type
        var person = new { Name = "Terry", Age = 34 }; 
Anonymous types:
 
var v = new { Amount = 108, Message = "Hello" };

Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to first explicitly define a type

Comments [0] | | # 
# Wednesday, December 23, 2009

See: http://www.programgood.net/2009/10/20/TestDrivenDevelopmentInNETDALCh5.aspx

ADO.NET (ActiveX Data Objects) consists of two primary parts:

Data provider

These classes provide access to a data source, such as a Microsoft SQL Server.  Each data source has its own set of provider objects, but they each have a common set of utility classes:

  • Connection: Provides a connection used to communicate with the data source.
  • Command: Used to perform some action on the data source, such as reading, updating, or deleting relational data.
  • Parameter: Describes a single parameter to a command. A common example is a parameter to a stored procedure.
  • DataAdapter: A bridge used to transfer data between a Data source and a DataSet object (see below).
  • DataReader: Used to efficiently process a large list of results one record at a time. It allows records to be accessed in a read-only, forward-only mode, i.e., records have to be accessed in sequential order; they can neither be randomly accessed nor can a record which has been processed previously be accessed again.
DataSets

DataSet objects, a group of classes describing a simple in-memory relational database,

  • A DataSet object represents a schema (either an entire database or a subset of one). It can contain tables and relationships between those tables.
    • A DataTable object represents a single table in the database. It has a name, rows, and columns.
      • A DataView object overlays a DataTable and sorts the data (much like an SQL "order by" clause) and filters the records (much like an SQL "where" clause) if a filter is set. An in-memory index is used to facilitate these operations. All DataTables have a default filter, while any number of additional DataViews can be defined, reducing interaction with the underlying database and thus improving performance.
        • A DataColumn represents a column of the table, including its name and type.
        • A DataRow object represents a single row in the table; it allows reading and updating of values in that row, likewise retrieving any rows that are related to it through a primary-key foreign-key relationship.

OLE-DB is a replacement for ODBC.

image

When adding in a reference (a COM – Component Object Model).. I had to restart VS to get Resharper/VS to recognize and give me intellisense.

The reference was an ADOX reference – ADO ext 2.8 for DDL and Security.  We have to use this as the OLE DB features do not give create new database functionality.

int index;
        string newDB;
        string dbName = txtDatabaseName.Text;
        try
        {
            if (dbName.Length == 0)
                return;
            index = dbName.LastIndexOf('.');
            if (index == -1) // no secondary filename
            {
                dbName += ".mdb";
            }
            string pathName = Application.StartupPath.ToString();
            string combinedName = Path.Combine(pathName, dbName);
            ADOX.CatalogClass myCat = new ADOX.CatalogClass();
            newDB = CONNECTSTRING + combinedName + ";" + CONNECTSTRINGPART2;
            myCat.Create(newDB);
            myCat = null;
        }
CreateDatabase_website

image

Good bit of functionality, if you double click on an element in the list, it deletes it.

void lstFieldsToAdd_DoubleClick(object sender, EventArgs e)
    {
        ListView.SelectedIndexCollection indexes = lstFieldsToAdd.SelectedIndices;
 
        foreach (int index in indexes)
        {
            lstFieldsToAdd.Items[index].Remove();
        }
    }

Writing to the database he uses a class in clsDB called ProcessCommand

However to read data he does this from a form object.  So only using the clsDB to get the connection string.

OleDbConnection myDB = new OleDbConnection();
OleDbDataReader myReader;
OleDbCommand myCommand;
clsDB myData = new clsDB("Friend");
 
try
{
    myDB.ConnectionString = myData.getConnectString + dbName;
    myDB.Open();
    if (txtLastName.Text.Length != 0)
        sql = "SELECT * FROM Friend WHERE LastName = '" +
              txtLastName.Text + "'";
    else
        sql = "SELECT * FROM Friend WHERE ID = " + txtRecordID.Text;
  
    ClearFields();
 
    myCommand = new OleDbCommand(sql, myDB);
    myReader = myCommand.ExecuteReader();
    if (myReader.Read() == true)
    {
        record = (int)myReader[0];
        txtRecordID.Text = record.ToString();

image

Querying and DataGrid

image

Changing properties on the grid, such as docking to allow window resizing, colour schemes, formatting of cells.

Double click on the database table automatically runs the execute query.  User can drag column headers around, and sort each column.  User can add/edit/del data (code not implemented in this example).

image

LINQ

image

var query = from p in numbers // the linq query
                    where p > lo && p < hi
                    select p;
        foreach (var val in query) // display results
        {
            lstOutput.Items.Add(val.ToString());
        }

image

This is an interesting construct, using anonymous types.  What this is actually saying

var friends = new[]
                      {
                          new {name = "Tom", state = "IN"},
                          new {name = "Alice", state = "VA"},
                          new {name = "Tammy", state = "IN"},
                          new {name = "Ann", state = "KY"},
                      };

 

var query = from p in friends
                        where p.state == txtLow.Text
                        select p;
 
            foreach (var val in query)
            {
                lstOutput.Items.Add(val.name.ToString() + ", " + val.state.ToString());
            }
Comments [0] | | # 

 

Uses recursion.  And System.IO

image

Had a debugging issue in the code, where there was an extra space which caused a –1 to be displayed in Directories found.

The catch block in the class was suppressing the error, so I put in a throw statement in the catch block which stopped the VS debugger, and pointed me to the correct place.

catch (Exception ex)
{
   //throw;  // great while debugging to get the line number of the exception
   return -1;
}
Error Logger

A useful class that writes to a textfile log, then can read back from it.  Creates the file if it doesn’t exist.  Appends to the file if it does exist.

image

Reading:
string pfn = Path.Combine(pathName, fileName);
            if (File.Exists(pfn))
            {
                sr = new StreamReader(pfn);
                buff = sr.ReadToEnd();
                sr.Close();
                return buff;
            }

Writing:
sw = new StreamWriter(Path.Combine(pathName, fileName), true);
                sw.WriteLine(currentDT.ToShortDateString() + ", " +
                             currentDT.ToShortTimeString() + ": " +
                             errorMessage);
                sw.WriteLine("-----------------------------");
                sw.Close();
Random Access Files

image

Uses frmMain for display logic, and clsRandomAccess for writing and reading data to disk.

In clsRandomAccess there are Property Methods for all fields:

public string FirstName
    {
        get
        {
            return firstName;
        }
        set
        {
            if (value.Length > 0)                   // Do we have a string?
            {
                firstName = value;
                if (firstName.Length > NAMESIZES)   // Too long
                {
                    firstName = firstName.Substring(0, NAMESIZES);  // Trim it.
                }
            }
        }
    }

All methods return a 0 if error, otherwise 1 if success.  Uses a binarywriter, and has to calculate the size of each record to know where to read to.

 

Serialize and Deserialize

image

Uses [Serialize] attribute on clsSerial class.

/// <summary>
 /// To serialize the contents of the class
 /// </summary>
 /// <param name="serial"></param>
 /// <returns>0 on error, 1 otherwise</returns>
 public int SerializeFriend(clsSerial myFriend)
 {
     try
     {
         BinaryFormatter format = new BinaryFormatter();
         FileStream myStream = new FileStream("Test.bin", FileMode.Create);
         format.Serialize(myStream, myFriend);
         myStream.Close();
     }
     catch (Exception ex)
     {
         string buff = ex.Message;
         return 0;
     }
     return 1;
 }
Multiple Document Interface

image

Comments [0] | | # 
# Monday, December 21, 2009

Before tackling generics, I had to understand the Quicksort algorithm.  Uses recursion.

From http://www.mycstutorials.com/articles/sorting/quicksort

image

Here is the

And back to the beginners book :-)  Here I am using the preprocessor directives in the frmMain class to make sure I get the same random numbers each time I run the app.

#define DEBUG
//#undef DEBUG

image

Onto Generics:

image

image

image

Pretty cool the same algorithm can sort these different kinds of data.  The reason they can is that each of these types implements a method called CompareTo.

public class clsQuicksort<thing> where thing : IComparable   //thing has to implement IComparable ie implements CompareTo.

And we can check that the type passed in implements CompareTo, by checking that it implements the IComparable interface.

using generics here so I can do this:

clsQuicksort<int> iSort = new clsQuicksort<int>(iData);
clsQuicksort<long> lSort = new clsQuicksort<long>(lData);
clsQuicksort<double> dSort = new clsQuicksort<double>(dData);
clsQuicksort<string> sSort = new clsQuicksort<string>(sData);

otherwise I would have had to make a different sort class for each type (just like that top of this blog article)

clsSortIntegers mySort = new clsSortIntegers(data); // passing the integer data array to be sorted through the constructor
mySort.quickSort(0, data.Length - 1); // sort the data
Refactorings:
/// <summary>
    /// Rather than doing a case statement to switch between displaying the iData, lData, dData, sData
    /// which is all in context, it is less code to write a generic method to handle this.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="stuff"></param>
    void ShowGenericData<T>(T[] stuff) // so can pass any type in here that implements ToString
    {
        for (int i = 0; i < stuff.Length; i++)
        {
            if (whichListBox == SORTED)
                lstSorted.Items.Add(stuff[i].ToString());
            else
                lstUnsorted.Items.Add(stuff[i].ToString());
        }
    }
 
and another:
/// <summary>
    /// Performs the data swap for quickSort()
    /// </summary>
    /// <param name="pos1">index to first value to swap</param>
    /// <param name="pos2">index to second value to swap</param>
    //void swap(int pos1, int pos2)
    //{
    //    thing temp;
    //    temp = data[pos1];
    //    data[pos1] = data[pos2];
    //    data[pos2] = temp;
    //}
 
    /// <summary>
    /// rewritten swap method that does not rely on class scope.  
    /// can take any type of data
    /// </summary>
    /// <param name="pos1"></param>
    /// <param name="pos2"></param>
    void swap<T>(T[] stuff, int pos1, int pos2)
    {
        T temp = stuff[pos1];
        stuff[pos1] = stuff[pos2];
        stuff[pos2] = temp;
    }

This is very nice as we have

  • strong type checking
  • no boxing/unboxing
  • no casting hasstles
Comments [0] | | # 
# Friday, December 18, 2009

image

rb – Radio Button

cbk - Checkbox

cmb – Combobox

dtp – DateTimePicker

Debug helper code

int exp1 = 5;
int exp2 = 0;
try
{
    throw new ArgumentOutOfRangeException();
    int result = exp1 / exp2;
}
catch (DivideByZeroException)
{
    MessageBox.Show("Expression 1 is 0, please reenter");
}
catch (Exception ex)
{
    MessageBox.Show("Bad things are afoot:\r\n" + ex.Message + "\r\n" + ex.StackTrace);
}
finally {
    MessageBox.Show("and finally");
}
Comments [0] | | # 
Chrome and Google

Ctrl Enter to open link in new tab

Up / Down arrow to select different search items

VS2010

Shift Del – deletes line and puts into clipboard

Ctrl Space – intellisense

Ctrl – , Ctrl Shift -    Jumps forwards, back to where you are editing.

Ctrl +

Alt R, Alt R – Refactor, Rename (F2 has stopped working for some reason).. or Shift F10, R R

Control , – Goto something

Control . – import namespace

Ctrl + E, D   Format Document

Shift + F10, U   Run tests.. only does 1 if in that test.

Ctrl R Ctrl T – Run Test (in debug).. to get Test Window to open, run the app (say forms app) and open the window.  it remembers!

Ctrl R, T – Run test

Ctrl R A = Run test in current context

Shift Alt C – Add class

VS2008

Shift Alt Enter – Full Screen

Ctrl + M, O – Collapse all methods

Ctrl + M, P – Expand all methods

Ctrl M, Ctrl M – Collapse / Expand current method

Ctrl + Alt – navigate between methods quickly

Ctrl -     - if you go to a method, this brings you back to where you were

Ctrl space – intellisense

Ctrl . – puts in a using statement (if needed)

Alt V P – View Solution

Alt V V – View Server Explorer (DB)

VS – Web

Alt B H to publish a website

Alt B O to select configuration manager

Ctrl Shift N – hides non visual controls.. clashes with resharper

Resharper

Alt Enter – do stuff

Alt Insert – Resharper generate

Ctrl Shift R – Refactor (ie to extract a method)

Ctrl + Q – Resharper.. documentation

Alt Up / Down – go to next member / tag

Ctrl Shift N – go to a file

Ctrl Shift Alt N – go to a method anywhere

VS – MVC

ctrl M, ctrl C – add a controller

ctrl M, ctrl  V – Add a view

Vimperator

:set guioptions+=mT   - have created an autohotkey script for this

:mkv!  - save settings

 

j and k – up and down

ctrl d and ctr u – page up and down

shift G and GG – bottom and top

/ – search

N – next… shift N previous

:qa and shift zz and   - exit

d – delete tab

Shift H or alt left arrow - back

O to open a URL with current page selected

t – tabopen

f – follow

F – follow in new window

gt flip between tabs

escape up arrow – shows the history in vimperator!

:qmark g http://www.gmail.com   - adds a quickmark

gog   - goes to the quickmark g  (gmail in my case)

Windows

tab tab – on login screen (winxp) this highlights the box

win l – lock

win d – minimize

win e – explorer

explorer type ph quickly to go to the first directory starting with ‘ph’

alt f4 – close

shift alt space n – minimize (with launch installed, otherwise alt space n)

Alt Tab

Alt Esc – cycle through open windows

F4 – Alt D  - display address bar in explorer

Shift F10 – right click

Ctrl Escape – display start menu

Backspace – go up a level in windows explorer

Win M – minimize

Win SHIFT M – restore

Nul Lock + Asterisk – in explorer display all subfolders under this one

Win F – Find (am trying out Windows Search 4.0)

 

Quicktime Player

L – fast forward

K – fast backwards

Outlook

F9 – Send and Reeive All

Programming Winform Element Names

txt – Text Box

lbl – Label

lst – Listbox

rb – Radio Button

cbk - Checkbox

cmb – Combobox

dtp – DateTimePicker

mnu – Menu Options (that go in MDI)

Language

rvalue – register value

lvalue – location value

MDI – Multiple Document Interface

RDC – Really Dumb Code

Comments [0] | | # 
# Monday, December 14, 2009

Was trying to figure out why something worked: http://stackoverflow.com/questions/1896871/c-calling-a-method-and-variable-scope

From http://rapidapplicationdevelopment.blogspot.com/2007/01/parameter-passing-in-c.html and Jon Skeets: http://www.yoda.arachsys.com/csharp/parameters.html

 

static void Main(string[] args)
    {
 
        int i = 5; // #1 a value type.. i and j are both 5, but seperate
        int j = i; 
        j = 10;
        Console.WriteLine(i); // prints 5
 
        StringBuilder sb1 = new StringBuilder("2.hello"); // #2 a reference type
        StringBuilder sb2 = sb1;  
        sb2.Append(" world");
        Console.WriteLine(sb1); // prints 2.hello world
 
        string s1 = "3.hello"; // #3 Immutable reference type
        string s2 = s1;  // s1 and s2 actually point to the same memory location now
        s2 += " world"; // seems like they split now.. behave like value types
        Console.WriteLine(s1); // prints 3.hello
 
        int a = 5; // #4 Value type passed by value
        Change(a); // equivalent to instantiating a new variable and assigning it the the first.
        Console.WriteLine(a);  // prints 5.
 
 
        StringBuilder ssb1 = new StringBuilder("5.hello"); // #5 reference types passed by value
        CChange(ssb1); 
        Console.WriteLine(ssb1); // prints hello world
 
        int g = 5; // #6 value type passed by reference
        DChange(ref g); 
        Console.WriteLine(g); // prints 10
 
        StringBuilder sssb1 = new StringBuilder("7.hello"); // #7 reference type passed by reference
        EChange(ref sssb1);
        Console.WriteLine(sssb1.ToString()); // null ref exception
 
        Console.ReadLine();
    }
 
    static void EChange(ref StringBuilder sssb2)
    {
        sssb2.Append(" world");
        sssb2 = null;
    }
 
    static void DChange(ref int g)
    {
        g = 10;
    }
 
    static void CChange(StringBuilder ssb2)
    {
        ssb2.Append(" world");
        ssb2 = null;
    }
 
    static void Change(int b)
    {
        b = 10;
    }
Value types:

int, etc..

Reference types

Arrays eg int[]

List<T>

Class, Interface, Delegate and Array types are all reference types.

Immutable Reference Types:

string

Comments [0] | | # 

 

On overloaded constructors, call the default constructor.  Constructor chaining

public clsDates(int yr) : this()

public clsDates()

Property Methods (getters and setters)

Cohesion – make a method do a single task only

Coupling - (Method coupling) ability to make changes in one method without forcing changes in another… ie make each method so it can operate independently

Deck of Cards

image

I’ve simplified the example given in the book to:

private void btnShuffle_Click(object sender, EventArgs e)
    {
        clsCardDeck myDeck = new clsCardDeck();
        int numberOfIterations = myDeck.ShuffleDeck();
        lblResult.Text = numberOfIterations.ToString();
 
        // display the newly shuffled deck in the multiline textbox.
        int deckSize = myDeck.DeckSize;
        for (int i = 1; i < deckSize+1; i++)
        {
            txtOutputResult.Text += myDeck.getOneCard(i) + " ";
        }
    }
 
then for clsCardDeck
 
public int ShuffleDeck()
{
    int index;
    int val;
    Random rnd = new Random();
    passCount = 0; // count how many times through the while loop
    index = 1;
    Array.Clear(deck, 0, deck.Length); // initialise the deck array to 0's
 
    while (index < deck.Length) // loop probably 52 times.. initialised at the top of this class.
    {
        // add 1 to the offset 0-based array
        val = rnd.Next(DECKSIZE) + 1; // Generates values between 1 - 52
        if (deck[val] == 0) // Is this card place in the deck "unused"?
        {
            deck[val] = index; // yep, so assign it a card place.. ie put the index number into a random spot
            index++; // get ready for the next card
        }
        passCount++;
    }
    return passCount;
}
 
/// <summary>
/// Show a given card in the deck
/// </summary>
/// <param name="index">the index of the position where the card is found</param>
/// <returns>the pip for the card, or empty or error</returns>
public string getOneCard(int index)
{
    if (index > 0 && index <= deck.Length && nextCard <= deck.Length)
        return pips[deck[index]]; // returns the 6H style string of the deck.
    else
        return ""; // error
}

Sideways Refinement:

1. Initialize – build and display the main form (frmDave)

2. Input – none

3. Process – Shuffle the deck (clsCardDeck)

4. Display – Show deck on 4 rows (frmDave) –> which uses Get One Card at a Time (clsCardDeck)

Clear Deck (frmDave)

5. Terminate – Close (frmDave)

this helped in thinking which class had which responsibilites.

InBetweenGame

You deal 2 cards, then bet on the outcome of the hidden 3rd card. Shown below I bet on a card coming up between 9D and QS.  It was a 3H, so I lost.

Debug information is in the textbox to the right hand side.

Source here

image

The architecture uses a middle ‘tier’ of rules, and a CardDeck class as used above.

Sideways Refinement:.. showing the responsibilities of each class.  Very useful.

1. Initialise – build and display the form (frmMain) – get initial wager and balance (clsRules)

- Do initial shuffle (clsCardDeck)

2. Input – get amount of wager (frmMain)

- ask for new cards.. deal.. (frmMain)

- ask for bet (frmMain)

3. Process – deal a hand (rules)

- enough money to bet (frmMain)

- enough cards in deck (clsCardDeck)

- no? shuffle (clsCardDeck)

- Get three cards (clsRules)

- Figure out winner and position to display card (clsRules) **note here it knows the winner after deal button is pressed

- make a bet (frmMain)

4. Display - display if TIE, WIN, LOSE message and adjust balance (frmMain)

- display card in correct position (frmMain)

5. Terminate – Close

This was interesting code:.. see post on this blog on Parameter Passing in C#.

// get three cards, result, and position to display
 // nb cards is a reference type (all arrays are), so don't need a ref.. it will be changed here.
 myRules.DealHand(cards, ref betResult, ref position);
Comments [0] | | # 
# Saturday, December 12, 2009

Continuing in the book series.

Part III, Chapter 9 – Designing Classes

Major benefits from OOP

  • Data encapsulation
  • Code reuse

Write a class that determines the date of Easter, and whether it is a leap year.

5 Programming Steps:

  1. Initialization
  2. Input
  3. Process
  4. Display
  5. Terminate
UML Light and Static

- daysInMonth : static int[]

// regardless of how many instances of this class you create, you get only one array named daysInMonth.

// the – means it is private..

// properties.. generally we want to hide as much as possible.

Use static with any data that can be shared between instances of classes

or any data that must be present the moment the program is ready to start executing

Code is here

image

This is how the author likes to set out his classes..

using System;
 
public class clsDates
{
    // PROPERTIES
    // symbolic constants
    // static members
    static int[] daysInMonth = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
 
    // instance members.. this is the common term for all non-static properties.
    int day;
    int month;
    int year;
    int leapYear;
    DateTime current;
 
    //METHODS
    // constructor
    public clsDates()
    {
        current = new DateTime();
    }
 
    // property methods
    // helper methods
    // general methods
 
    /// <summary>
    /// Purpose:  To determine if the year is a leap year.
    /// </summary>
    /// <param name="year">the year under construction</param>
    /// <returns>1 if a leap year, 0 otherwise</returns>
    public int getLeapYear(int year)
    {
        if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
            return 1; // it is a leap year
        else
            return 0;
    }
 
    /// <summary>
    /// To determine the date for Easter given a year
    /// </summary>
    /// <param name="year">int year - the year under construction</param>
    /// <returns>the date in DateTime as MM/DD/YYYY format</returns>
    public string getEaster(int year)
    {
        int offset;
        int leap;
        int day;
        int temp1;
        int temp2;
        int total;
 
        offset = year % 19;
        leap = year % 4;
        day = year % 7;
        temp1 = (19 * offset + 24) % 30;
        temp2 = (2 * leap + 4 * day + 6 * temp1 + 5) % 7;
        total = (22 + temp1 + temp2);
        if (total > 31)
        {
            month = 4; // Easter is in April
            day = total - 31; // on this day
        }
        else
        {
            month = 3; // Easter is in March
            day = total; // on this day
        }
        DateTime myDT = new DateTime(year, month, day);
        return myDT.ToLongDateString();
    }
}

I loved his irreverant style Exercises:

Q: Give a good example of where you would use the public access specifier to define a class property?

A: I couldn’t think of one either :-)

SOC = Show Off Code :-)

Comments [0] | | #