Jun 26, 2008

C# filtering List of abstract objects to a List of concrete objects (is vs. as vs. OfType + ToList()).

In many cases we may want to extract a list of concrete object types from a list with more abstract types.

For example if we have a List of users, we may want to extract another list of users which are administrators (let’s suppose administrator inherits user).

I did some very basic tests to check which approach will be faster to achieve this (by faster I mean optimized, not faster to write). I used a List with 10,000,000 elements of type object, filled with int objects and string objects. The goal was to retrieve a Lits of int objects only, as fast as possible.

For now I have 3 candidates to do this (if you know more - please write a comment):

Candidate 1 : Iterate the collection with foreach, get each element as object, cast this
element to nullable int (int?) (using “as” operator) and see if it is null.
Candidate 2 : Iterate the collection with foreach, get each element as object and check it with “is” operator against int type.
Candiate 3 : Use OfType with ToList, which is only one line of code.

Let’s see the classes (I did a separate class for each approach)

class ISSample
{
public static void StartSample(List<object> objects)
    {
        
int processed = 0;
        
List<int> intList = new List<int>();
        
long ticksStart = DateTime.Now.Ticks;
        
foreach (object obj in objects)
        {
           processed++;
          
if (obj is int)
           {
             intList.Add((
int)obj);
           }
        }
    
long ticksEnd = DateTime.Now.Ticks;
double result = Convert.ToDouble(ticksEnd - ticksStart) / TimeSpan.TicksPerSecond;
        
Console.WriteLine("IS executed for : " + result.ToString("N10")
+
" seconds, items processed: " + processed);
}
}

class ASOperatorSample
{
public static void StartSample(List<object> objects)
    {
    
int processed = 0;
        
List<int> intList = new List<int>();
        
long ticksStart = DateTime.Now.Ticks;

        
foreach (object obj in objects)
        {
           processed++;
          
int? obj2 = obj as int?;
          
if (obj2 != null)
           {
             intList.Add((
int)obj2);
           }
        }

        
long ticksEnd = DateTime.Now.Ticks;
double result = Convert.ToDouble(ticksEnd - ticksStart) / TimeSpan.TicksPerSecond;
Console.WriteLine("AS executed for : " + result.ToString("N10") + " seconds items processed: " + processed.ToString());
     }
   }

class OfTypeSample
{
public static void StartSample(List<object> objects)
    {
    
List<int> intList = new List<int>();
        
long ticksStart = DateTime.Now.Ticks;

        
// Here is how this is done in C# 3.5 style
        // with one line only
        intList = objects.OfType<int>().ToList<int>();
        
        
long ticksEnd = DateTime.Now.Ticks;
        
double result = Convert.ToDouble(ticksEnd - ticksStart) / TimeSpan.TicksPerSecond;
        
Console.WriteLine("OfType executed for : " + result.ToString("N10") + " seconds.");
}
}


Now let’s see some outputs:

AS executed for : 5.3281250000 seconds items processed: 10000000
IS executed for : 0.3750000000 seconds, items processed: 10000000
OfType executed for : 0.7812500000 seconds.
Press any key to continue . . .

AS executed for : 5.6562500000 seconds items processed: 10000000
OfType executed for : 0.7812500000 seconds.
IS executed for : 0.5312500000 seconds, items processed: 10000000
Press any key to continue . . .

OfType executed for : 0.9375000000 seconds.
AS executed for : 5.5468750000 seconds items processed: 10000000
IS executed for : 0.3906250000 seconds, items processed: 10000000
Press any key to continue . . .

As you can see there is slight difference in the results depending on which approach will we call first. The obvious thing is that Is operator is always faster, followed by the OfType and the last place is for AS operator.

You may note that for the “is” and “as” operators I added “items processed:” portion. This is very important - by using foreach you can do some statistics inside the loop, while using OfType won’t let you write any code inside the loop.

Jun 25, 2008

C# var - the difference between invariant type (JavaScript and other languages) and C#

The var keyword in C# (which is not even a keyword as you are permitted to create a class "var") is different from javascript.
The difference is that once assigned, a variable pefixed with a var "keyword" will have the type of what was assigned and will only allow you to assign object of the same type to this variable (or objects which inherit from that object).

Here is a brief example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;

namespace LINQ
{
  
class Program
   {
    
static void Main(string[] args)
     {
        Sample();
     }
    
static void Sample()
     {
        
style="color:Blue;">var a = new object();
        a =
new OperationCanceledException();
        
Console.WriteLine(a.GetType().Name);
     }
   }
}

Note, that we first assign new object to the variable a. After this assignment, "a" will only accept variables of type object (or any other type, which inherits from object). Then we assigned OperationCanceledExceptionObject (which inherits object type through Exception). If you try the opposite - to first assign
OperationCanceledException variable and then object you will end up with exception.


Conclusion: with var you are forcing the compiler to infer the type of the right side variable automatically. You will not need to declare what the type of variable should be. This saves you the following:

object a = new object();

What's nice is that Microsoft Visual Studio 2008 will be able to determine the type of a also and offer you intelisense.

May 28, 2008

How to catch specific MSSQL exception in .NET?

This one is pretty interesting. Not quite sure how useful, but it is good to know it.

For the following example you will need one SQL table. I have a table called products. It has a column ProductName (NVARCHAR(10)), which we will use so I can show you how to catch specific SqlException and pass over all other SqlExceptions (actually re-throw them).



As you may or may not know the Sql namespace has one exception which is generic and is thrown no matter what caused the exception inside the SqlServer, .NET will always throw SqlException.



So how can we distinct the different Sql Errors?

Let’s make a short demo so I can show you. First of all, as I said, we will have a table (in my case Products).

The ProductName column is set to be
unique, so if a product with the same name already exist in .NET we will have SqlException, but in Sql the things are different. There we will have something like:



Msg 2627, Level 14, State 1, Line 1

Violation of UNIQUE KEY constraint 'p'. Cannot insert duplicate key in object 'dbo.products'.



Let’s say we want to catch only the “Unique violation” exception and leave all other exceptions propagate.



Let’s setup a very small form to illustrate this. We will have two labels, one text box and one button. When clicking on the button the text in the text box will be added in the Products table. If there is already product with the same name we will display the second label.

Simple isn’t it?



Here is the form:



<asp:Label ID="lblProductNameCaption" runat="server" Text="Product name:" />

<
br />

<
asp:TextBox ID="txtProductName"

         runat="server"

Width="259px">

asp:TextBox>

<
br />

<
asp:Label ID="lblError"

runat="server"

        
Visible="false"

        
ForeColor="red"

        
Font-Size="x-small">

asp:Label>

<
br />

<
asp:Button ID="btnSaveProduct"

        
runat="server"

        
OnClick="btnSaveProduct_Click"

        
Text="Save"

Width="79px" />



In order to distinct the unique constraint violation we need to compare it to something. Fortunately SqlException type transports the ErrorNumber from the SqlServer straight to .NET, so we can use it.

We need to find out the number for that particular exception. In a previous post I wrote where can you obtain information about all errors in Sql Server.

Okay, we know the error number of Unique Constraint Violation.

Let’s write some code to handle it:



const int uniqueConstraintViolaton = 2627;



This constant you may define as global so you can access it across your code.



The magic comes in the
btnSaveProduct_Click:



SqlConnection con = new SqlConnection("connection_string");

con.Open();

SqlCommand cmd = con.CreateCommand();

cmd.CommandText =
"Insert into products " +

"(productname)" +

            
"values " +

            
"('" + txtProductName.Text + "');";

try

{

cmd.ExecuteScalar();

}

catch (SqlException sqlException)

{

if (sqlException.Number == uniqueConstraintViolaton)

    {

    
this.lblError.Text = "Product already exist.";

        
this.lblError.Visible = true;

     }

    
else

     {

    
// Pass over ...

        throw sqlException;

     }

}



What we did? We caught SqlException in the
catch block.

We tested if it is the Sql error we are expecting. If it was - we performed some actions to inform the user.

If it wasn’t - we re-thrown, so if there is some exception handling code - it could receive it and handle it as expected.



When you type in a name of a product which already exist in the database you should see the label showing, informing you that there is a product with that name.

To test if other exceptions are propagating, you may type a name with more than 10 symbols (I set my ProductName column to be NVARCHAR(10)). You should see exception which informs you that the data would be truncated. Your code will not handle this, but pass it over.




Literature which may be useful: Microsoft SQL Server 2005 Unleashed, Microsoft SQL Server 2005 For Dummies, Pro ADO.NET 2.0, Programming Microsoft® ADO.NET 2.0 Core Reference

How to get all Microsoft SQL Server errors

This can be achieved by using the sys.sysmessages system view. You may want to specify language to prevent errors localized in all available languages to be returned.
English should be with 1033 id.

Here is a query which will return all the errors for English:

select * from sys.sysmessages where msglangid=1033


Literature which may be useful: Microsoft SQL Server 2005 Unleashed, Microsoft SQL Server 2005 For Dummies
>

May 26, 2008

Enumerators - the correct way to parse an enumerator.

First of all - what are enumerators?

You can think for the enumerators as for some kind of constants. They are used to check objects against.

Let's say you will have the following dropdown:



<asp:DropDownList ID="ddlGender" runat="server">

<asp:ListItem Value="1">Maleasp:ListItem>

<asp:ListItem Value="2">Femaleasp:ListItem>

<asp:ListItem Value="3">Won't shareasp:ListItem>

asp:DropDownList>



As you know the genders won't ever change, for code convenience, you may want to define an enumerator to hold them, so you can check against:



enum EnumUserGender

{

Male = 1,

Female = 2,

Unknown
= 3

}



This way, the Male element of the enumerator will have a value of 1, Female will have a value of 2 and Unknown will have a value of 3.

To check a value against enumerator you may do the following:



int Gender = 1;

if (Gender == EnumUserGender.Male)

{



}



In this case the if will evaluate to true, as the Gender variable has a value of 1.



Now, let's return to our case with the
asp:DropDownList, we want to be able to know which asp:ListItem was selected by the user. We don't want to convert the value to int first, but to receive it as a EnumUserGender variable. Let's do this in the SelectedIndex SelectedIndexChanged asp:DropDownList:



protected void ddlGender_SelectedIndexChanged(object sender, EventArgs e)

{

EnumUserGender genderSelected = (EnumUserGender)Enum.Parse(typeof(EnumUserGender), ddlGender.SelectedValue, true);

switch (genderSelected)

{

case EnumUserGender.Male:

Response.Write(
"Check our cars section!");

break;

case EnumUserGender.Female:

Response.Write(
"Check our make-up section");

break;

case EnumUserGender.Unknown:

Response.Write(
"If you want you can check either our cars section or our make-up section");

break;

default:

Response.Write(
"Sorry, there was an" +

"error, please go back and try again," +

" the error was logged and will be reviewed by our team.");

break;

}

}

}



What we did was to actually Parse the
Enum , by using its base class method Parse. It recieves 2 parameters + 1 optional:



Parameter 1 is of type
Type, this is the type to which the enumerator will be parsed / converted. In our case we use the typeof, function, passing our enum type as a paramter.

Parameter 2 is of type
string, this is the value to be parsed.

Parameter 3 is of type
bool, and indicates whether the value passed as a string should match case sensitive. If set to true, you will have insensitive Parse, so "mALe" will be parsed correctly.



May 16, 2008

Changing asp:RequiredFieldValidator (why not any validator) in existing projects relatively easy

The last post I posted was about changing the asterix of asp:RequiredFieldValidator (I don’t see a reason this not to work for any validator). My friends Georgi and Vesko noticed that I am not thinking about how can we apply such a change in a big project.
They also provided me with a solution to this problem. The solution is pretty good; it uses the control adapters approach to change the span which is rendered as output.

But I found another way, I consider more elegant. Instead using the control adapter approach, you can simply repeat the following steps:

1. Right click on your project and choose Add -> ASP.NET Folder -> Theme
2. Name your theme folder “Default” for example.
3. Right click your theme folder and choose Add -> New Item

4. From the Add New Item dialog choose “Skin File”, name it “Default.Skin” and clik OK
5. Open “Default.Skin” file and add the following code


<asp:RequiredFieldValidator runat="server">
   <img src="~/images/validator.png" width="15" height="15"/>
asp:RequiredFieldValidator>

This will register the default behavior for asp:RequiredFieldValidator controls on your site.

6. Add the above code for all validators you want to affect.
7. Open your web.config file and find the section
8. Register the theme you just created like this :

<pages theme="Default">

So it can propagate throughout all of your pages.

Add as much as validators you want on ANY page of your site. The web.config declaration should take care to apply your generic skin to all validators on your pages.

Please note - if you have explicitly defined Theme for a page - the web.config declaration will be overridden, in such case - you may want to move you control declarations from the skin in the Default theme to a skin in the theme which is set for a page you want this changes to take effect.

Good Luck!

May 14, 2008

asp:RequiredFieldValidator (or any asp validator perhaps?) control with image instead asterix

I was wondering how can I create required field validator with image, instead this ugly asterix, used in most forms.

The answer was pretty obvious but I couldn't see it for quite a long time. I even decided to write my own validator to inherit from RequiredFieldValidator and hopefully overwite the HtmlTextWriter thing in order to achieve this functionality.

The solution is pretty strightforward, you don't need new controls, you don't need anything, all you need is :



<asp:TextBox ID="txtFakeTextBox" runat="server">asp:TextBox>

<asp:RequiredFieldValidator ID="rfFake" runat="server" ControlToValidate="txtFakeTextBox" Display="Dynamic" EnableClientScript="true">
/><asp:Image ID="imgTest" runat="server" ImageUrl="~/images/error.png"/>

asp:RequiredFieldValidator>

<br />

<asp:Button ID="btnOpenFakeValidator" runat="server" Text="Validate!" CausesValidation="true" />





What you do is to place and control between the opening and closing tags of the asp:RequiredFieldValidator. Pretty easy, huh?




May 4, 2008

Cancel post back based on user confirmation

Okay, in my first post in the ASP.NET rookies I said I will explain how you can have a button which will first ask you if you are sure you want to do particullar action.



I did the example with a simple button, not with GridView as it does'n matter, the logic is the same.

First of all let's create new Web Application. My application name is "ASPNETRookies" as I plan to use this project not only for this demo but in the future for other demos.
Open the Default.aspx page in Visual Studio 2005 designer and place a button on the form:

<asp:Button ID="btnConfirmation" runat="server" Text="Chameleon Bulgaria"/>

I used "btnConfirmation” for ID and "Chameleon Bulgaria" to be shown as caption. If you have a grid for example, you will have some functionality to delete the user for which the button is pressed and probably to repopulate this grid with the users left in the database. To keep it simple I added very basic functionality to this button - our button will simply redirect to a site. So if the user confirms the dialog - he will be redirected to the site, if not - the post back should be cancelled and he should stay on the same page. To add the redirection part do the following:

Double click the button in designer view so Visual Studio can generate onclick handler (remember that this is the code behind onclick event handler. The code in it will be executed on the server, not on the client machine, so you should see that the page does post back).
Here is what I wrote in my onclick event handler:

    
protected void btnConfirmation_Click(object sender, EventArgs e)
     {
        Response.Redirect(
"http://chameleonbulgaria.com");
     }


Now let's see how can we implement the rest of the logic - to have a confirmation box which asks the user something. The javascript function which asks the user a question and returns true or false according to his answer is Confirm('Text'). This will open a confirmation box with two buttons - OK and Cancel. If the user choose "OK" the Confirm function will return true, otherwise - it will return false. Okay, we know what we need, but where to place this code?

Well there are few ways to assign client click handler on ASP.NET button - all of them however, rely on the "OnClientClick" property. It receives the javascript which will be executed as a string. You can assign the name of a javascript function, or, alternativelly - the javascript code (only short code, please!). You can assign this property through the ASP.NET markup of the button (in the Default.aspx page) or you can assign it in the code behind (Page_Load handler for example). Okay, if you add it now as I did, you will have something like this:

    
<asp:Button ID="btnConfirmation"
            
runat="server"
            
Text="Chameleon Bulgaria"
            
OnClick="btnConfirmation_Click"
            
OnClientClick="confirm('Do you want to go to Chameleon Bulgaria?');" />

Now run the project and click on the button. You will see the confirmation box. If you click on the "Cancel" button you should stay on the same page, but wait ..., what is going on? The button click event is raised again. This means we failed to complete our mission.
Now let’s think a bit. We see the confirmation box before the page is posted back to the server. So all we need to do is to somehow cancel the post back. Typically the button is rendered as submit html element. So what it does is to call our form .submit() method. Okay how can we cancel submit? By adding “return false” is the answer. When the browser see “return false” it will stop the execution of the javascript statement. Try this with our button. Add “return false” to the OnClientClick, removing our confirm for a while.

Okay we understood that we need to cancel the submission of the form, we understood how we can do this. Now let’s put all things together - we have a confirm() which returns true or false based on which button the user clicked. So in order to achieve the right functionality we need to add “return” before our confirm method like this:


OnClientClick="return confirm('Do you want to go to Chameleon Bulgaria?');" />


Try to run the project now. It should work just as expected. When you click “Cancel” the page won’t be sent back to the server.

Apr 24, 2008

ASP.NET Newbies

Hi to all my readers!
I haven't been blogging for some time but I was extremely busy those days. A lot of things happened - I am leaving my work, I am starting new one, some offers which I couldn't accept and so on, I hope all the things that recently happened are for good (actually I am sure).

I am posting now to let you know that I will try to organize my time in such a manner so I can have enough of it to deal with something I promised to few friends of mine.
The promise was to start writing posts to help them get better in web development. They are starters yet and have read the books they need to read but we need to figure out how can they learn things that can't be learnt from the books. They need some practical examples and this
is what I will try to do.

I decided to start something like a Tips & Tricks section so those of my friends which alread read one of the ASP.NET books can benefit from those posts.

I think the most difficult thing for a newbie is to connect the dots. They have read for MSSQL, for C#, for ADO.NET, DataSets, C#, XML, Web Services, AJAX, wooow isn't this too much?
Typically when a newbie read a book - the book contains some practical examples and projects. And typically those projects are not so user friendly, I don't think there are projects in a book to utilize the client scripting for example.
If you are ASP.NET rookie can you answer the following question:

"You have a button which needs to do something in the code behind, but before it does this it should ask the user if he / she is sure he wants this thing done. For example you have a grid with clients. The grid also contains a column with buttons to delete client. When the user clicks on a delete button for a client, a confirmation box should popup asking him is if he / she is sure the client should be deleted. This thing should happen without post back to save users time."

I think most of you will not be able to answer this question as it is not quite popular ASP.NET books to contain also JavaScript lessons.
This is what I will try to do - to learn you (from what I know offcourse) how to tie different technologies to achieve the best user experience.

Mar 31, 2008

Never tought I will need Award Images module on my site ...

I recently built a PAD generator script on my site in order to easilly promote my software, but I never tought my software will be awarded. The surprise came from Sedo Auctions Watcher, it was awarded 5 stars by redsofts.com (you can find my program listed here). Becouse I built this little tool for few hours and it wasn't doing anything than informing you on ending domain auctions I was pretty surprised. What's even more interesting is that Sedo Auctions Watcher is adware program. It displays banners, but it does this by following some guidelines. It will not change your homepage or install toolbars.

Probably because I was trying to play fear I was awarded. What's good is that this award changed the way I think. After 4-5 hours of work
were awarded, what will happen if I spend some more time?

You'll see soon ;)

You can find the rating guidelines here:

http://www.redsofts.com/awards.html

Mar 24, 2008

Finally its here ...

Skype passport 1.0 is out, you can find the simple html page on Chameleon Bulgaria



Online demo: Here



Download page: Here
>

Mar 20, 2008

World's first Skype Passport is almost out ;)

This is a little javascript which will allow your users to easilly register on your site, by filling their contacts automatically from skype (offcourse only few fields are populated, but most registrations require only few fields after all).
Here is a screenshot of this neat little javascript placed on a page:



Note : This works only if your users are using IE (as this thing depends on ActiveX).

The tool will be available for free download at my site : ChameleonBulgaria so visit it regularly ;)

When I publish it, I will also publish a news on the frontend so you can know.
Just a few more hours ;)
.

Mar 19, 2008

Very simple tool to watch ending Sedo Auctions

Few months ago I was interested in the domain trading business. It was interesting to me as it generated 14.2 million dollars back in 2006. It is based on speculla I think. Something like FOREX but not quite.

I registered two domains and placed them on Sedo Auctions.

I was also interested on how other domains are going so I decided to write a small tool. It will stay in your tray and will show you the auctions which are about to end the next 24 hours. The following information is gathered about each auction:

- Domain for sale
- Price
- Currency
- Time left before the auction is closed
- Google PR for each domain

The program is available for download from Chameleon Bulgaria

I decided to put a banner on this program so my domains
for sale are visible to the users (well, after all I spent some time on this program and I would really like ot have some incomes after all ;).

Here is a direct link to the program page on Chameleon Bulgaria may be found
here

Mar 16, 2008

5 minutes C# to dispose your NotifyIcon object

If you have this problem - try calling .Dispose() method for your NotifyIcon explicitly in the FormClosing event:


    
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
     {
        notifyIcon1.Dispose();
     }

Note : this trick may not work if the Application was terminated abnormally. I will investigate that issue when I have some free time and report back what is the best approach on this.
>

Mar 13, 2008

5 minutes to have your web.config keys in order


This time I will not post any C# codes ;). I will only inform you that I am in the middle of the development of two small tools which will (hopefully) make deployers life easier.
The first one is used to create simple web.config plans - you will be able to create plans for your sites and use those plans in the future to check if everything is in order.
The second one is what I call "the player" it will receive those plans and play their recorded actions against selected sites. This way you can always check if some of your sites is still configured properly. After the check is completed - you will be able to export the results to CSV file so you can use them as a checklist.


Another post will be posted here when the tools come out and you will be able to find them (free of charge) on my site ChameleonBulgaria.com, so check it too (by the way the site is Under Construction but I will complete it too, unfortunatelly I am the only person to work on it, but this is also subject to change).


I also plan to develop the ability those tools to receive the site / host name and output file name as a parameters so they can be scheduled easilly to run on their own, so all you will need to do is take a look at the files from time to time to make sure everything is still working smooth.

Mar 7, 2008

Bulgarian IT Boxing - We (.NET team and fans) lost round 2, waiting for round 3 now ...

Last night the second round of Bulgarian ITBoxing took place.

What is ITBoxing?
ITBoxing is an event where developers using different platforms gather and present the advantages of their platform. After all the technologies are presented the audience votes about their favourite technology.

Last night the following technologies were presented (votes included):

Java 73 votes.
.NET 45 votes.
Ruby on Rails 13 votes.
PHP 11 votes.

This was the second round so now Java and .NET are on the top (the first round was for .NET ;). I was disappointed to understand that my technology wasn't first this time.

Round 3 will be held in about a month or so and the topic will be Enterprise development. Hopefully there will be less Java
developers in the audience this time so we can win again ;). I think we deserve it ;).

NOTE: I wasn't in the .NET team, I was in the audience but tried to help with comments against Java ;).

No matter which technology wins I think those events are very helpful for all develeopers, as after all - our work is to complete our job on time and with less efforts. When you attend such events you can inform yourself about which type of tasks are easier to complete with Java, which with .NET, which with PHP and which with Ruby.

Feb 29, 2008

5 minutes C# to build a Zoo with Marker Interfaces.

First of all what is marker interface?
A marker interface is an empty interface which defines no fields, but is only there for reference.

Let's start with the case study and we will go through the example and explain everything.


Case Study : Build a simple Zoo program.
You have a Zoo with few animals - those animals are only fishes and birds. As this Zoo is relatively small it has only one employee to feed all the animals with the appropriate food. The fishes eat food which we will refer to as "fishfood" and the birds eat a food which we will refer to as "grains".

To accomplish this we may create an interface, which identifies the things that are common for both types of animals in the Zoo.

IAnimal.cs

using System;
using
System.Collections.Generic;
using System.Text;

namespace MarkerInterface.Objects
{
  
interface IAnimal
   {
    
void Feed(FoodType food);
    
bool Hungry
     {
        
set;
        
get;
     }
   }
}

Ok, we gave the animals the ability to eat, but how will the employee identify what kind of food to feed them with?

Let's first define an enumerator to hold the food types:

Food.cs:

using System;
using System.Collections.Generic;
using System.Text;

namespace MarkerInterface.Objects
{
  
public enum FoodType
   {
     Grains,
     Fishfood
   }
}

Ok, we have the food types now. In order to split the animals in the Zoo in two separate groups we are going to use the Marker Interface, we will define two interfaces to mark which animal is fish and which is bird.

IBird.cs:

using System;
using System.Collections.Generic;
using System.Text;

namespace MarkerInterface.Objects
{
  
interface IBird : IAnimal
   {
    
   }
}

Now let's do the same for the fieshes:

using System;
using System.Collections.Generic;
using System.Text;

namespace MarkerInterface.Objects
{
  
interface IFish : IAnimal
   {
    
   }
}

Now let's have two concrete animals - one for each type:

Heller.cs:

using System;
using System.Collections.Generic;
using System.Text;

namespace MarkerInterface.Objects.Animals
{
  
class Heller : IFish
   {
     #region IFish Members
    
private bool hungry = false;
    
public void Feed(FoodType food)
     {
        
if (food != FoodType.Fishfood)
        {
          
throw new ArgumentException("Heller is a fish and eats only fishfood.");
        }
        
else
        {
          
this.hungry = false;
        }
     }

     #endregion

     #region
IAnimal Members

    
public bool Hungry
     {
        
get
        {
          
return this.hungry;
        }
        
set
        {
          
this.hungry = value;
        }
     }

     #endregion
   }
}

Chicken.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace MarkerInterface.Objects.Animals
{
  
class Chicken : IBird
   {

     #region IBird Members
    
    
bool hungry = false;

    
public void Feed(FoodType food)
     {
        
if (food != FoodType.Grains)
        {
          
throw new ArgumentException("The chicken only eats grains.");
        }
        
else
        {
          
this.hungry = false;
        }
     }

    
public bool Hungry
     {
        
get { return this.hungry; }
        
set { this.hungry = value; }
     }

     #endregion
   }
}

Let's have one employee to feed the animals:

ZooEmployee.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace MarkerInterface.Objects
{
  
class ZooEmployee
   {
    
public delegate void OnAnimalFeeded(string Animal, string FoodType);
    
public event OnAnimalFeeded AnimalFeeded;

    
public void FeedAnimals(List<IAnimal> animals)
     {
        
foreach (IAnimal animal in animals)
        {
          
if (animal is IFish)
           {
             animal.Feed(
FoodType.Fishfood);
            
this.AnimalFeeded(animal.GetType().Name, "fish food");
           }
          
if (animal is IBird)
           {
             animal.Feed(
FoodType.Grains);
            
this.AnimalFeeded(animal.GetType().Name, "grains");
           }
        }
     }
   }
}

NOTE: I added the OnAnimalFeeded delegate and the AnimalFeeded event, so the Zoo employee can report to us when it has feeded an animal.

Let's define the Zoo class:

Zoo.cs

namespace MarkerInterface.Objects
{
  
class Zoo
   {
    
List<IAnimal> animals = new List<IAnimal>();
    
List<ZooEmployee> employees = new List<ZooEmployee>();

    
public Zoo()
     {
        animals.Add(
new Animals.Chicken());
        animals.Add(
new Animals.Heller());

        
ZooEmployee employee = new ZooEmployee();
        
this.employees.Add(employee);
     }

    
public List<IAnimal> Animals
     {
        
get { return this.animals; }
     }
    
public List<ZooEmployee> Employees
     {
        
get { return this.employees; }
     }
   }
}

Now, in the main form of the program we will instantiate the Zoo class, and call its employee to feed all the animals.

On the form I added one button and one RichTextbox. When I click the button the following code will get executed:

        Objects.
Zoo zoo = new MarkerInterface.Objects.Zoo();
        zoo.Employees[0].AnimalFeeded +=
new MarkerInterface.Objects.ZooEmployee.OnAnimalFeeded(Form1_AnimalFeeded);
        zoo.Employees[0].FeedAnimals(zoo.Animals);

What are we doing here - we are simply creating a Zoo, we are using it's first employee (as we said it will always be exactly one emplyee) AnimalFeeded event to report when what animal is feeded and with what food and we are then asking the employee to feed the animals.

The marker interfaces here are used in the ZooEmployee.FeedAnimals() method to help the employee decide which type of food to give to each animal.

As the Chicken inherits from the IBird the employee will feed it with grains. As the Heller inherits from IFish it will be feeded with fish food.

Here is the Form1_AnimalFeeded which is fired each time the employee feeds animals. It will be used to display in the RichTextBox what is our employee doing at the moment:

    
void Form1_AnimalFeeded(string Animal, string FoodType)
     {
        
this.rtbAnimalsFeeded.AppendText(Animal + " was feeded with " + FoodType + "\n");
     }

Here is how it looks like after it was runed:



Hope you understood it ;).

Feb 10, 2008

businesscatalyser - a game?

Well, after I was too bored today I decided to do something interesting. So I made my own game. I decided to buy a domain and park it on the sedo auction, I also listed it for sale.

So here are the rules:
1. Park the domain and try to get as much clicks as possible (no spam or other black techniques).
2. List it also for sale but don't try to sell it for less then 1K EU (just to be more interesting)
3. You may use only home made software and public sites services in order to promote the site.

Here is the site : BusinessCatalyser.com (don't laugh about the name, I wanted to have some very competitive keyword in the domain(business) so the game can be even harder and more interesting.

You may say this is a madness or losing time, but
as I was wondering how to promote this thing I made a little software which you may use in order to promote your sites. It is a small program which takes the words and searches for a sites with similar content, checks the PR of the sites found and reports you where it will be good to write a post.


Here are the basic stats of BusinessCatalyser.com :

SmartPageRank.com says this site costs 0 USD
Sedo.com says it is for sale and has no content, no PR, no links
It currently has 0.00 EU from the parking affair.


If you are interested in this game I will be happy to exchange information with you, just write a comment ...

Thanks for the attention ;)

Feb 9, 2008

sealed class usage

We recently started an internal academy in our company to improve our software development skills. The first meeting was about OOP fundamentals, it was really interesting (thanks Vesko for your efforts!). This question appeared as interesting for me - when should we use the sealed class.

Some collegues guessed it should be used in the most concrete classes, as they will not be used as a base classses, but I don't think so. After all - why should you say : "Hey, don't use this thing as a base class" explicitly after you know it will not be used anyway.

I did soem research on the net about the sealed class usage, it appeared it's common use is for classes with static methods. The example I've found was about Brush and Pen .NET
objects. They are sealed as they have only static fields like : .Blue and so on.

So when you are doing software you may keep in mind that you have that sealed thing to help you limit the inheritance of your classes.

Feb 6, 2008

Is Microsoft the source of all evil or what?

It is very strange, I was searching for a migration tools, just to see how this market is going. I accidently found this thing here:




What's so strange? Some people choose weird domains to run business under. The strange thing happened after I clicked on the link to see what's behind:



Finally I decided to type the url address in my browser to see actual site behind thesource.ofallevil.com and see where it redirected me:

>

Feb 4, 2008

5 minutes C# code to load CSV file into a DataSet


Step 1 : add button for browsing files, a textbox to hold the file name and paste the followin code in the browse button click handler (this code will basically popup a OpenFileDialog, set up to only open files with .csv extension):

             OpenFileDialog ofd = new OpenFileDialog ();
            ofd.Filter =
"CSV Files|*.csv" ;
            
if (ofd.ShowDialog() == DialogResult .OK)
            {
               
this .textBox2.Text = ofd.FileName;
                GetData();
            }

Then we need to get the file from the textbox2 and load it into data set:

      
private void GetData()
       {
            
FileInfo fi = new FileInfo (textBox2.Text);
            
OleDbConnection con = new OleDbConnection ( @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fi.Directory.FullName + ";Extended Properties='text;HDR=Yes;FMT=Delimited'" );
            con.Open();

            
DataSet dsThings = new DataSet ();
            
OleDbCommand cmd = new OleDbCommand ( "SELECT * FROM " + fi.Name, con);
            
OleDbDataAdapter adapt = new OleDbDataAdapter (cmd);
            adapt.Fill(dsThings);
            
this .dataGridView1.DataSource = dsThings.Tables[0];
            
       }

As you can see we use OleDB provider to load the CSV file into the dataset.