| |
| Sat, Aug 2, 2008:
Mon, Aug 11, 2008:
Mon, Aug 18, 2008:
Thu, Aug 21, 2008:
Sat, Aug 23, 2008:
Mon, Aug 25, 2008:
Tue, Aug 26, 2008:
Mon, Sep 15, 2008:
|
INFYMUS .COM
© 2006-2008 Michael S. Hoenie Hosted by FasterPing Compiled With: Caligra 1.10 | 4 JUN 2008
No portion may be used without express permission of Michael S. Hoenie aka Infymus. |
|
|
|
PLEASE NOTE:
If you have reached this page from an outside source such as an Internet Search or forum
referral, please note that this page (the one you just landed on) is an
archive containing articles on
"PROGRAMMING - C#"
from a Blogger named Infymus. This website,
INFYMUS.COM
- is a blog belonging to INFYMUS. Click "MAIN" on the Main Menu to see current blogs.
|
|
|
PROGRAMMING - C#
Microsoft Visual C# - A language I began coding in August, 2008.
Total Articles:
9
|
|
Today I installed Microsoft C# 2008 Express and wrote my first "Hello World" program:
Aren't I special? I've done plenty in Visual C# 2003 and 2005, but this is my first look at 2008.
|
I have been spending about four to five hours a day concentrating on learning C# 2008. I'm about a quarter of the way through this 800-page book now. I find that the C++ and C# language is untamed, dirty and without eloquence. It doesn't flow, it has no beatifying structure, and it cuts corners and is downright sloppy. I've found that things that Pascal has been able to do (now Delphi) since 1984, it seems that C# just hasn't figured out yet and procedures, methods and function calls are sloppy and archaic.
Take for instance a function in Delphi. A function in Delphi that returns an integer can be easily picked up in a variable.
Delphi function:
function MyFunction : string;
begin
Result := 'Hi There';
end;
From the calling procedure you could say:
x := MyFunction; { as X would be a string }
But in C# you have to go about it totally different:
In C# you have to capture the function's result set and then do something with it. So you have twice the lines of code to do the same thing.
C# function:
private void addValues()
{
result.Text = "Hi There"
}
The calling procedure:
addValues();
catch (Exception X)
result.Text = X.Message;
Ok, you can do this:
string MyWeirdFunction( string InString )
{
return( InString );
}
And then get the value this way:
string x;
x = MyWeirdFunction("Hi There");
Want to evaluate a Boolean?
In Delphi:
if MyObject.Checked then do { This will work}
In C# you have to:
if ((bool)addition.IsChecked) { } // there is no THEN DO, only brackets { }
You can Type Cast in Delphi when you have to find the calling object type, but it seems you have to type cast in C# all of the time.
It is interesting how C# uses HTML files as their Form object storage containers. Delphi uses .RES files. In Delphi, you can view forms as source and see the container objects. Delphi protects you from the Form source and maintains it. C# puts it in your face and if you make a small mistake, it is difficult to get back out. On top of that, the IDE Form on the screen has to be constantly re-drawn into HTML. This is a pain in the ass. As I have coded in C#, I've had to constantly click on the warning for C# that the HTML needs to be re-rendered so to speak. As I've said, C# is sloppy and archaic, yet so many companies seem to think that Microsoft is God's gift to Coding and lets all jump on the goddamn bandwagon.
But back to the HTML, if you drag and drop a button onto your form, the button doesn't appear in your source code. It's stored as an HTML container inside of the HTML source file. In Delphi, dragging and dropping a button onto your form places the object type of tbutton into your form's main object class. You can see it. You can interact with it. You can make it private, you can make it public. You can move it around, or you can create it on the fly and parent dock it onto any form you want. In C#, it goes into the HTML file and you have to switch back and forth between two separate source code files to actually find it. And because it's XML, it has all of the properties inside of the HTML at once, rather than those items being hidden from you and shown inside of the Properties window. This adds another level of complexity to C# and is the fundamental reason why the visible Form in front of you has to be re-calculated from the HTML file. IMO, it's an interpretation which builds the form from the HTML. Perhaps this has something to do with the .NET architecture allowing to transfer a form object onto a web platform, but I haven't gotten that far into C# yet to figure out the method to their madness. Not having the class declaration inside of your main block of code almost makes it as if the class doesn't exist - because it's not in front of your eyes, it hides somewhere else.
Delphi is a beautiful coding language and it works quickly and efficiently. It connects to all major back end databases such as Microsoft SQL Server and Oracle, not to mention a host of other lower end databases such as MySQL, Access, DBASE and Paradox. To me, Borland was so anxious to jump on the .NET bandwagon that they sacrificed the Delphi name in Delphi 8 and unwittingly caused the downfall of the language.
I think what bothers me the most about the C# environment is the IDE. Everything is scrunched together on one screen. You can't separate out the RAD screen from the source code screen. Both are set together on a tab. So you have your RAD, your source and your HTML (.RES) file all together on tabs. And you have to hit key combinations just to switch between them. In Delphi, you can un-dock your IDE Form from your source code and have them in two separate windows. That way you can have your Form on your first monitor and your source code on the second. C# forces everything in one place and the only thing you can un-dock is your component palette, object browser and project manager. At least you can do that. It is interesting to note that Delphi 8 took this same approach and broke over two decades of editing styles. Later on, Delphi 2005 allowed you to actually detach the Form from the palette and separate out your code from Tabbed pages. Tabbed pages are great for editors or web pages, but don't force me to put the Form on the same page and make me click tabs to get back and forth or Ctrl- something or Shift- something. It's highly annoying.
Oh, and yes, case sensitive coding is annoying and time consuming. A variable is a Variable is a VariAble, but not in C. Each of those three variables are three separate variables.
Delphi:
Var
Infymus : Integer;
Useage:
Infymus, INFYMUS, InfyMUS, InFyMuS : All equal the same thing regardless, one variable.
C#:
int Infymus;
int INFYMUS;
Useage:
Infymus and INFYMUS are two separate variables because they are case sensative.
While Delphi requires that all functions and procedures outside of an object block be defined up front, C# has no such rules. You can create a function right in the middle of something else, declare variables that have already previously been declared and then use them. If you aren't careful, you will create some seriously sloppy spaghetti code. I've seen some pretty nasty million line coded Delphi applications, but I can't even fathom companies that have been writing C# applications for several years in an unstructured, undocumented or functional specification-less environment. I can only imagine the millions of lines of spaghetti band-aid approached coding out there.
Delphi's IDE is based on the original Turbo Pascal IDE which is based on the original STAR editor environment. Things like CTRL-Y to delete a line and bring all lines up, CTRL-KD and CTRL-KK and so forth made editing very easy. C# IDE doesn't seem to conform to anything more than a bloated Notepad editor. It takes longer to move the text around in the IDE than it would otherwise take simply because you have to use the mouse a lot more to cut, paste and code.
One of the lead coders (Anders Hejlsberg) that brought us Turbo Pascal from Borland and early Delphi versions went to work for Microsoft years ago. He created J# or J++ and then moved on to C#. You can see so many things stolen from Pascal and Delphi in C#. Uses clauses are among some of the simplest forms of this. You can see his hands all over the place.
Over the last two weeks I have learned how to make several different kinds of applications in C#. I've found out how to make procedures and functions within the main block of code. I've done math, string and integer conversions, popup messages and so forth.
What I'm looking forward to is creating classes and seeing how C# handles them, and how you can create lists of objects that are controlled by singular objects. I'm also looking forward to creating new forms, calling them and freeing them when finished. I hope that C# has the ability to create a form dynamically and then dock said form onto an already existing form. Delphi does this with ease so you would think a much older base language of C++ would also be able to do so. But of course, C# is C++ with an IDE and a RAD environment wrapped around it, so who knows.
Is C# just an old horse with a pretty dress and makeup on or is it really a tool that can create on-the-fly real world applications? I'll find out shortly.
|
Last week I went through variables, switch statements, Boolean operators, and methods in C#.
Bear with me as I ramble on with my C# learning. It's cathartic and helps me to go over the procedures, functions, methods, algorithms, variables and methodologies of C# in comparison of them to Delphi. In doing so, I more solidify the code base in my head.
In Delphi you have Procedures and you have Functions. Both can receive input, but only Functions return some kind of result set. There are no Procedures or Functions per say in C#, only what they call "Methods". Methods encompass both the Functions and Procedures.
Delphi Function that passes in no variable but returns an integer:
Function SomeKindOfFunction : Integer;
C# that passes in no variable but returns an integer:
int SomeKindOfFunction()
Delphi Procedure that passes in an integer:
Procedure MyProcedure( InVal : Integer );
C# Procedure that passes in an integer:
void MyProcedure( int InVal )
The "void" represents that the "method" will not be returning a value. Remember, in C# there are no differences between Functions and Procedures, so we have to use "void".
There are other factors on a method that can be used such as Private or Protected, but I won't get into that until I start looking at Classes.
Case statements are called Switch statements in C#.
Delphi example:
Function MyFunction( InVal : Integer ) : String;
Begin
case InVal of
1:result := 'One';
2:result := 'Two';
3:result := 'Three';
else result := 'WTF?';
end;
In C# it's more complicated and on top of it all, you have more verbose commands or it won't work:
string MyFunction(int InVal)
{
switch (InVal)
{
case 1:
return ("One");
break;
case 2:
return ("Two");
break;
case 3:
return ("Three");
break;
default:
return ("Wtf?");
break;
}
}
C# requires that you "break" after each case otherwise the code will "fall" into the next set of code. Why doesn't the compiler just terminate and "exit" the method when it is done? Why does it require the programmer to physically type "break" after each section? Who knows, if you don't put in breaks, the compiler will error out stating that commands are not allowed to "fall through".
C# or C++ uses three times the amount typing as Delphi does, so coding will take two or three times longer than a proficient Delphi coder would. I used brackets { } above, but they are not necessary in C#, even so, I'll continue to use them by force of habit.
Simple things in Delphi such as "AND", "OR", and "NOT" are more cryptic in C#.
In Delphi you could say:
If (MyBool1 = True) and (MyBool2 = True)
But in C# you would say:
if (MyBool1) && (MyBool2)
Which of course, is more cryptic, but less typing in this particular case. For ease of reading code and simply understanding it, it doesn't catch your eye as fast as the prior Delphi called statement.
AND is &&, NOT is !=, OR is || (pipe pipe).
The rest of the standard operators such as <, <=, >, >= are the same, while C# adds ++, --, !=, && and ||. Syntactically they do exactly the same thing as Delphi.
If / Then / Else blocks are identical, however, I have to remember to use the brackets rather than BEGIN and END, which of course is difficult to remember. Delphi uses brackets { } as comments and not as blocks of code.
Delphi:
var
seconds,minutes : integer;
...
begin
seconds := 0;
minutes := 0;
If x = 59 then
begin
seconds := 0;
inc(minutes);
end
else
inc(seconds);
end;
In C# you would do it this way:
int seconds = 0;
int minutes = 0;
...
if (x == 59)
{
seconds = 0;
minutes++;
}
else
seconds++;
If you need more "else" statements, you can cascade them with "else if" the same way that Delphi does it.
It's all a mind set, and it can be a frustrating mindset when you put together a "method", and hit compile and you're constantly getting build errors on improper use of parenthesis () in the wrong places, or a semi colon left off where it should be, or as said before, lack of parenthesis where they should be.
"WHILE" statements are identical to Delphi While statements, and I haven't found a suitable solution for Delphi's Repeat. A While statement will do the same thing. Delphi would say "Repeat (something) Until (Something)" or "While (Something) do (Something)" and both are relatively the same thing.
In Delphi:
var
i:integer;
...
begin
while i < 10 do
inc(i);
end;
In C#:
{
int i = 0;
while (i < 10)
{
i++;
}
}
I think what pisses me off the most about the C# editor at this point, other than it being a bloated text editor, is that when you write code, but the code can't compile, the error stays in the code until you fix it and you can't get help on the command UNTIL you get it right.. If you click on a piece of code that is a C# command such as "ToString", but you have it incorrect such as this:
int mystring = someinteger.ToString; // This line will fail, there are no () on the end of ToString
int mystring = someinteger.ToString(); // Correct, will compile
The C# IDE compiler will break on the line because the () are missing. If you click on the "ToString" and then press F1, the compiler won't go find "ToString", it will bring up "Compiler Error CS0103" or some other such error, leaving you in the dark to try and figure out HOW to use the said command. Once you get it right, then you can click on the "ToString", press F1 and it'll take you to said help context (providing the command is a actually C# command and not something you made yourself.) What a load of frustration it is and goes back to my original statement that C# is bloated, untamed, dirty and without eloquence.
This week I will be finally learning Classes and Objects and I'm dying to get my hands into them. But first I have to learn a little more of the IDE debugging, stack walking, handling exception errors and so forth.
Should be a couple more days.
|
This week I am working through Class Objects in C#. It is interesting to see how C# does encapsulation and inheritance. Constructors, Deconstructors, Property methods and more are easily handled by Delphi, but seem to be a step more complicated in C#. I would say it isn't so much that they are more complicated, but just three times the amount of typing to solve the same problem. In Delphi you can create your object, press CTRL-SHIFT-C, and the source code from the object will be created below the Object. You can then go in and fill the detail. In C#, it is all done by hand.
Here is a Delphi Class Object:
tInvoiceLineObject = Class(tObject)
PRIVATE
fBackOrdered : Boolean;
fBackOrderType : Integer;
fCost : Currency;
fSellAtCost : Currency;
fProductType : Integer;
fSoldQuantity : Integer;
Function GetTotalCost : Currency;
PUBLIC
CONSTRUCTOR Create( InBackOrdered : Boolean; InBackOrderType : Integer; InCost : Currency; InSellAtCost : Currency; InProductType : Integer; InSoldQuantity : Integer); OVERLOAD;
PROPERTY TotalCost : Currency READ GetTotalCost;
end;
You instantiate the Class Object in Delphi this way:
LineObject := tInvoiceLineObject.Create(true, 0, 0, 0, 0, 0);
You free it this way:
FreeAndNil(LineObject);
The above object contains several PRIVATE variables that are not exposed outside of the object. The CONSTRUCTOR overrides the Class Object's create method and allows arguments to be passed to the object for initialization. The PROPERTY TotalCost is a public variable that is assigned to a function called GetTotalCost.
TotalCost is visible outside the object and when accessed, the GetTotalFunction is called and the value is passed back through the TotalCost property.
All of the Delphi code is set outside the above class object, with a InvoiceLineObject.(ObjectName) call.
Here is the same Class Object in C#:
class tInvoiceLineObject
{
// Constructor method
public tInvoiceLineObject(bool InBackOrdered, int InBackOrderType,
double InCost, double InSellAtCost, int InProductType, int InSoldQuantity)
{
// do what is required here to initialize the object
}
// private Variables
double fAmountDue;
double fAmountTendered;
bool fBackOrdered;
int fBackOrderType;
double fCost;
double fSellAtCost;
int fProductType;
int fSoldQuantity;
private static double fTotalCost;
// Property Methods, private not exposed
public static double TotalCost()
{
return (fTotalCost);
}
}
You instantiate the Class Object in C# this way:
tInvoiceLineObject LineObject = new tInvoiceLineObject(true, 0, 0, 0, 0, 0);
You free it this way:
LineObject = null;
Unfortunately, C# uses a "Garbage Collection" to clear out unused variables, objects and what not. It only runs every X minutes, so your object, while null, may continue to exist.
In C#, all of the code is contained within the Class Object. The CONSTRUCTOR is basically the same name of the class, but with arguments passed for initialization. There are no property methods; you simply have to make PUBLIC STATIC Methods in order to be able to access those methods outside of the Class Object - including any variables you want to use INSIDE of Methods. In the above statement, if I hadn't made fTotalCost a "private", you could have accessed it outside the object. If I hadn't made it "static", then it couldn't be used in the TotalCost() method. Complicated.
So many little tiny rules to remember.
|
I have been converting all of my programs that I use on a daily basis over to C#. It helps me to practice coding in C#.
Here is my weather program.
Those of you who live in Utah, this is a great program. Small, you can put it on your taskbar. Click it any time to see real-time weather that is going on from Northern to Southern Utah, including Channel 2, 4 and 5. Dopplar, infrared, VIPER - all of it is included.
You can download this from Infymus Files..
|
| Connecting To A Microsoft SQL Server Database And Reading A Table Monday, Aug 25, 2008, at 11:41 AM PROGRAMMING - C# -GUID- | | |
Delphi handles this so much better, but I digress. This application I wrote today connects to a Microsoft SQL Server, opens a table called "Northwind", and reads the information out of it displaying it on the console. It could easily be converted to a Windows application and dumped into a Memo or something. Tomorrow I will be working my way through LINQ and DLINQ.
SqlConnection dataConnection = new SqlConnection();
SqlDataReader dataReader;
string customerId = "";
int orderId;
DateTime orderDate;
DateTime shipDate;
string shipName;
string shipAddress;
string shipCity;
string shipCountry;
SqlCommand dataCommand = new SqlCommand();
try
{
dataConnection.ConnectionString = "Integrated Security=true;Initial Catalog=Northwind;Data Source=infyhuge\\SQLExpress";
dataConnection.Open();
dataCommand = new SqlCommand();
dataCommand.Connection = dataConnection;
dataCommand.Connection = dataConnection;
dataCommand.CommandText = "SELECT * FROM ORDERS";
try
{
dataReader = dataCommand.ExecuteReader();
while (dataReader.Read())
{
orderId = dataReader.GetInt32(dataReader.GetOrdinal("OrderID"));
if (!dataReader.IsDBNull(dataReader.GetOrdinal("ShippedDate")))
{
orderDate = dataReader.GetDateTime(dataReader.GetOrdinal("OrderDate"));
shipDate = dataReader.GetDateTime(dataReader.GetOrdinal("ShippedDate"));
shipName = dataReader.GetString(dataReader.GetOrdinal("ShipName"));
shipAddress = dataReader.GetString(dataReader.GetOrdinal("ShipAddress"));
shipCity = dataReader.GetString(dataReader.GetOrdinal("shipCity"));
shipCountry = dataReader.GetString(dataReader.GetOrdinal("ShipAddress"));
Console.WriteLine("OrderID={0}\nOrderDate={1}\nShipDate={2}\nShipName={3}\n" +
"ShipAddress={4}\nShipCity{5}|\nShipCountry{6}\n\n",orderId, orderDate,
shipDate, shipName, shipAddress, shipCity, shipCountry);
}
}
dataReader.Close();
}
catch (SqlException e)
{
Console.WriteLine("Farkin Bombed: {0}", e.Message);
}
catch (SqlException e)
{
Console.WriteLine("Farkin Bombed: {0}", e.Message);
}
}
|
Variables in C#, suck. This has got to be the worst language I have ever seen with their scope of variables.
You can create variables on the fly. Create variables within For/Next loops. Create variables within Try/Catch blocks. Create variables inside of While loops.
Variables created within certain areas of C# code "fall out of scope" once you are out of the block.
In Delphi, you can do this:
var
x : integer;
begin
while x < 5 do
begin
inc(x);
end;
ShowMessage("X = " + IntToStr(x));
end;
In the above Delphi code, X always exists, period. It has been pre-declared and goes out of scope once the method has finished.
In C#, it is a whole different dimension. It is as if any block of code creates an instantiated method in which all declared variables fall out of scope once it is finished.
For instance:
int x = 0;
int y = 0;
while (y < 5)
{
x++;
y++;
}
MessageBox.Show("Value of X is " + x);
The above procedure will work because X and Y were defined BEFORE the while block. Note that the variables X and Y could be created right before your WHILE block, and not at the start of the method.
This one will fail:
int y = 0;
while (y < 5)
{
int x = 5;
y++;
}
MessageBox.Show("Value of X is " + x);
You will error on the last line because the name 'x' does not exist in the "current context".
Variables declared within TRY, FOR/NEXT, WHILE or other such blocks of code fall out of scope when the block is finished.
It is the craziest damn thing I have ever seen.
|
There are three different kinds of applications that you can create in Visual C#. A Windows Form Application, a Windows Presentation Foundation Client Application - which is .NET Framework, and a Console Application. There are a couple of others, but these three are the ones that I am concentrating on.
A C# Console Application allows you to create a formless application that runs in a CMD (or for you old timers, DOS) window. It uses the standard WriteLine, ReadLine aspects to read and write from the console line. I can see this useful for creating applications that adhere to strict coding practices to allow transport out of say Windows and into Linux. For me personally, I have not written, nor run a console application in over 10 years. When Windows 95 came out and Delphi 2 - everything switched to Forms and console applications were no longer necessary.
A Windows Presentation Foundation Client - or a WPF Application uses Extensible Application Markup Language (XAML) as a base code, along with internal C# coding. It is the essence of the .NET Framework. While XAML goes hand in hand with a WPF, they are not the same. XAML is a type of XML-markup language while WPF is a graphics API.
WPF is the new presentation API (Application Programming Interface) in .NET Framework 3.0 (formerly WinFX).
Users can program directly against the API with .NET, instantiate (render) WPF objects by expressing them in XAML, or employ a mixture of XAML with .NET code behind.
The WPF API has a wide range of functionality, from Windows controls like buttons to 3D graphics, special effects and multimedia. WPF enables the creation of items that presently require different file formats - for example, the equivalent of PDF, HTML, WinForms and Flash can be developed with WPF.
From what I can tell, WPF isn't used as much as C# is, although Microsoft has huge plans for WPF. Vista uses it and Microsoft SQL Server 2008 as well. From what I can gather on the web, it seems a general consensus that WPF architecture will actually take over Windows Forms, but we shall have to see.
Regular C# Windows Applications allows you to create standard Windows Forms applications. These applications can directly interact with a wide variety of back-end databases such as Access, Microsoft SQL Server or Oracle. Using the VCL, you can create forms with buttons, panels; drop down boxes and so forth. This is the most common form of C# Application.
The next few days I am studying LINQ and DLINQ. LINQ or Language INtegrated Query is a set of language and framework features that allow you to write queries directly in C#. LINQ drastically cuts the plumbing code required for database applications while reducing runtime errors (LINQ queries are statically type-checked by the compiler). LINQ can also query local in-memory collections and XML trees. Framework 3.5 ships with a lightweight new XML DOM designed for this purpose.
|
This weekend one of the questions that I failed in C#, well, failed the term, not the meaning behind the term - was delegates, or events.
Say you have two objects. First object is an invoice. The second object is an invoice_line_item. The invoice_line_item can contain things like line number, total amount, product number, quantity, etc. The invoice object creates an invoice_line_item object and controls it. If the invoice_line_item quantity changes, then the total amount on the invoice_line_item changes too. You want the invoice_line_item to tell the invoice that the quantity changed. How would you go about doing that?
In Delphi, you have to create a type handler of a type of OBJECT outside of the object.
TYPE
tQuantityHandler = Procedure( Sender : Tobject; TotalQuantity : Integer ) OF Object;
TYPE
invoice_line_item = class(tObject);
protected
fQuantityChanged : tQuantityHandler;
public
property OnQuantityChanged : tQuantityHandler READ fQuantityChanged WRITE fQuantityChanged;
end;
To invoke the handler inside of the object, you would do the following:
If assigned (fQuantityChanged) then
fQuantityChanged(Self, 5);
The invoice object has to have the invoice_line_item event set up before you can use it:
invoice_line_item.OnQuantityChanged := Handle_The_Line_Change;
The procedure "Handle_The_Line_Change" must be able to handle the return of a tObject and an integer.
In C#, it is far more robust. You can encapsulate the entire thing right inside of both objects.
Public class invoice_line_item
{
// note that the term "DELEGATE" is how you set up the method, it can be blank, or pass something back
public delegate void delegate_quantity_changed(int QtyChange);
// the term "EVENT" is used to tie the event to the delegate
public event delegate_quantity_changed quantity_changed_event;
public void calculate_invoice()
{
// we can call the event now.
quantity_changed_event(10); // the quantity just changed to 10, statically of course
}
}
In the invoice object, we do the following:
Public class invoice
{
// yes, we could and SHOULD do invoicelines in an object array
invoiceline invoiceline1 = new invoiceline();
// now set up a constructor so the event will fire anywhere in the object
public invoice()
{
// by invoking the +=, we assign the event in the invoice_line_item object to our method in the invoice object
invoiceline1.quantity_changed_event += new invoiceline1.delegate_quantity_changed(handle_qty_change);
}
// now create the handler
public void handle_qty_change(int inQtyChange)
{
MessageBox.Show("The Quantity Changed To " + inQtyChange);
}
}
What a beauty way to go, eh? C# is more strict than Delphi. In Delphi, you'd better test to make sure the calling object has instantiated an event handler, or you will access violate. In C#, if your object doesn't contain it, you can't compile.
|
|