Sunday, December 03, 2006

css tips: header, footer, and scrollable middle area full document

Back in the days, I used to start a page with a html table with 3 rows, one for the header, one for the middle area at 100%, and a footer

Nowadays this approach doesn't work any more and we're told that we have to use pure CSS, not tables, blabla... so, how do we accomplish this with pure CSS?

We are going to need some css and a bit of javascript, first of all, lets see the css

html,body,form
{
margin:0;
padding:0;
}//prevent some default spacing on some browsers
.header
{
text-align:center;
background-color:Navy;
color:White;
width:100%;
}
.footer
{
background-color:Orange;
color:Navy;
position:absolute;
bottom:0;
border:0;
}
div.scrollable{
overflow:auto;
border-left-width:0px;
border-bottom-width:0px;
border-top-width:0px;
border-right-width:0px;
background-color:Gray;
color:White;
position:absolute;
}

the most interesting is the last class div.scrollable, overflow:auto makes it scrollable, and the rest is to eliminate the borders and set the color.


Now lets see the html:

<html>
<head>
</head>
<link rel="stylesheet" type="text/css" href="test.css" />
<body>

<div>
<div id="header" class="header" height="20px">
This is the header
</div>

<div id="mainDiv" class="scrollable">
This is the main body<br>
There is a lot of stuff in the main
<br><br><br><br><br><br><br><br><br><br>
There is a lot of stuff in the main
<br><br><br><br><br><br><br><br><br><br>
There is a lot of stuff in the main
<br><br><br><br><br><br><br><br><br><br>
There is a lot of stuff in the main
<br><br><br><br><br><br><br><br><br><br>
There is a lot of stuff in the main
<br>
<br><br><br>
This is the last line
</div>

<div id="footer" class="footer" height="20px">
<div style="float:left">This is a div on the left</div>
<div style="float:right">This is a div on the right</div>
</div>

</div>

</body>
</html>

I put a lot of lines in the middle, just so you can see the document scrolling. As a "bonus" I put two divs on the footer, one aligned to the left and one to the right, both in the same "row", this is one of those things that people have a hard time finding. We're almost there, we just need some javascript now:

var mainDivHeight;
var mainDivWidth;

function AdjustFullSize() {
var screenHeight = 450;
var screenWidth = 610;

if (window.innerHeight) {
screenHeight = window.innerHeight;
screenWidth = window.innerWidth;
}
else if (document.body) {
screenHeight = document.body.clientHeight;
screenWidth = document.body.clientWidth;
}

mainDivHeight = screenHeight - 20 - 20; //20+20 for header and footer
mainDivWidth = screenWidth - 0;

document.getElementById('mainDiv').style.height = mainDivHeight + 'px';
document.getElementById('mainDiv').style.width = mainDivWidth + 'px';
}

The different browsers have different properties to access the document height and width, we account for that and then assign the size to the main div, call this function on the body onload (and resize!) and we are done, the end result looks like this, you can get the full source from there, hope you find it useful.

Wednesday, November 29, 2006

two checks in one with bool.TryParse

I just ran accross some code like this:

bool b = bool.TryParse(ConfigurationManager.AppSettings["SomeSetting"].ToString(), out b);

ignore the fact that I'm not checking for null on the appsettings.

At first sight I thought it was a bug, but then read the documentation, ran a little test and some investigation with Reflector, it turns out it does exacly what we needed to do

bool.TryParse doesn't return the value of converting the string passed to it; it returns true or false, indicating if the conversion succeeded, the value of the conversion is returned in the out parameter (which in this case was the same variable) so the only way to return true in that case is

  1. The conversion succeeded
  2. the value was true

so I don't need to say

if (bool.TryParse(someVariable, out b))

if (b)...

...little dangerous lines of code

Tuesday, November 14, 2006

Delphi has a new home

finally after what seemed like an eternity, Delphi has a new home (although still kinda living with it's parents, it will soon move out), no more Borland, it's now CodeGear

http://biz.yahoo.com/bw/061114/20061114006381.html...

Tuesday, November 07, 2006

Code reuse, next level

The code for this article is written in C# (tested in VS2005)

I'm still catching up with my blog reading; a few days ago I read an article on latindevelopers: sorting objects with IComparer (code in English, comments and article in Spanish); it reminded me of a common mistake: the use of conditional statements in (not so obvious) loops (e.g. callbacks) which results in a type of (not so obvious) code duplication.

In Delphi this error is commonly seen in component development, specifically on the Paint event where they use if statements to decide which font to use, colors, etc, and what's worst, many times an instance (of whatever objects are required) is created on each iteration; all those objects, of course, don't change unless you change properties of the component!!, so those should be cached and kept on variables where they can just be reused; yes, code reuse doesn't just mean re-using classes, or refactoring code into methods, caching objects is a form of code reuse because it avoids conditional statements and places code calls directly.

Let's see the code from the original example, specifically the PersonComparer class, it has a constructor which takes the SortField and stores that on a variable that is later used on the Compare method

public PersonComparer(SortField sortField) {
this.sortField = sortField;
}
public int Compare(object x, object y) {
if (!((x is Person) & (y is Person))) {
throw new
ArgumentException("Los objetos deben ser de tipo Person.");
}

switch (sortField) {
case SortField.Name:
return
Comparer.DefaultInvariant.Compare(
((Person)x).Name, ((Person)y).Name);

case SortField.LastName:
return
Comparer.DefaultInvariant.Compare(
((Person)x).LastName, ((Person)y).LastName);

case SortField.Age:
return
((Person)x).Age - ((Person)y).Age;

default:
throw new
ArgumentException("Tipo de ordenamiento desconocido.");
}
}

Perhaps you don't see it very clear because the example doesn't use generics, let's see what we could do using generics (there is a TimeZone2, so why can't I have my PersonComparer2?):

    public class PersonComparer2<T> : System.Collections.Generic.IComparer<T> where T:Person {
delegate int ComparerDelegate(T x, T y);
ComparerDelegate comparerDelegate;

Now we have a delegate declaration, a variable of that type and we got rid of the SortField variable, let's see the constructor:

public PersonComparer2(SortField sortField) {
switch (sortField) {
case SortField.Name:
comparerDelegate = delegate(T x, T y) {
return x.Name.CompareTo(y.Name);
};
break;
case SortField.LastName:
comparerDelegate = delegate(T x, T y) {
return x.LastName.CompareTo(y.LastName);
};
break;
case SortField.Age:
comparerDelegate = delegate(T x, T y) {
return x.Age - y.Age;
};
break;
default:
throw new
ArgumentException("unknown sort method.");
}
}

Instead of caching the SortField variable, I'm caching the method that will be executed when the comparison takes place; finally, let's see the actual Compare method:

public int Compare(T x, T y) {
return comparerDelegate(x, y);
}

do you see it? the decision of what method needs to be used for the comparison gets executed only once (on the constructor), then we can call it directly, instead of asking the same question over and over again on each iteration.

Every time you see a conditional statement on a loop or a method that gets executed in some kind of loop (like paint events, callbacks, etc) consider using this technique, it will help you build more structured and faster code, also consider using arrays or dictionaries of methods.

The concept applies to programming in general, but the implementation may vary from language to language, the main idea is to cache objects / methods in some way so you don't have to repeat conditional statements to create objects or decide which code block to execute.

The full code for this example can be found here, as always, play with it, learn from it, improve it.
kick it on DotNetKicks.com

Sunday, October 29, 2006

How to: Instantiate a class with a private constructor

Applies to C# (tested in VS2005)

On a recent post I talked about accessing (another's class) private methods through reflection; apparently not a lot of people was aware that this was possible. Well, here's another one for y'all, you can instantiate a class even if it's constructor is private

Here I'm including one example for a private constructor, one for protected and one for a (regular) public constructor, all of them using reflection.

Let's create our test class to play with:

public class TestClass {
private TestClass() {
Console.WriteLine("private TestClass constructor");
}
protected TestClass(int i) {
Console.WriteLine(string.Format("protected TestClass constructor (int:{0})", i));
}
public TestClass(string s) {
Console.WriteLine(string.Format("public TestClass constructor (string:{0})", s));
}
}

now let's see how easy is to instantiate this class using any of it's constructor, regardless of their visibility, all this through reflection:


- you need to include System.Reflection in your uses clause


The first one is a simple parameterless private constructor, not much is required here

//*** Private constructor
ConstructorInfo ci1 = typeof(TestClass).GetConstructor(
//*** Non public and instance (non static) constructor
BindingFlags.NonPublic | BindingFlags.Instance,
//*** No binder, no parameters, so no parameter modifiers
null, new Type[0], new ParameterModifier[0]);
//*** Call our constructor
TestClass tc1 = (TestClass)ci1.Invoke(new object[0]);
The second one is protected (you still still use "non-public" for the BindingFlags), 
it does include a parameter so we have to pass the parameter type
//*** Protected constructor
ConstructorInfo ci2 = typeof(TestClass).GetConstructor(
//*** non public and instance (non static) constructor
BindingFlags.NonPublic | BindingFlags.Instance,
//*** no binder, 1 parameter of type int, no modifiers for the param
null, new Type[1] { typeof(int) }, new ParameterModifier[0]);
//*** Call our constructor
TestClass tc2 = (TestClass)ci2.Invoke(new object[1] { 10 });
The third one is public, we could instantiate it without reflection, 
but I'll just leave it as an example. 
//*** Public constructor
ConstructorInfo ci3 = typeof(TestClass).GetConstructor(
//*** public and instance method
BindingFlags.Public | BindingFlags.Instance,
//*** no binder, 1 parameter of type string, no parameter modifiers
null, new Type[1] { typeof(string) }, new ParameterModifier[0]);
//*** Call our constructor
TestClass tc3 = (TestClass)ci3.Invoke(new object[1] { "test" });

That's it, that simple; this technique should rarely be used, more than anything I want you to be aware that it is possible and how easy it is


You could even combine the flags: BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance and it would instantiate the class if the access modifier was private, protected or public

You can find the full code here, have fun

By the way, I'm in Guadalajara now, I'll be here until Tuesday, then I'm going to Tulancingo Hidalgo and then Aguascalientes, if anyone wants to join me for dinner or just talk let me know


kick it on DotNetKicks.com

Thursday, October 26, 2006

Javascript madness

Found this on Javi Moya's blog

1. Highlight the text below
2. Ctrl+C
3. Alt+D (Ctrl+L in opera) (or just go to the address bar)
4. Ctrl+V
5. [Enter]

javascript:scroll(0,0); R=0; x1=.1; y1=.05; x2=.25; y2=.24; x3=1.6; y3=.24; x4=300; y4=200; x5=300; y5=200; DI=document.getElementsByTagName("img"); DIL=DI.length; function A(){for(i=0; i-DIL; i++){DIS=DI[ i ].style; DIS.position='absolute'; DIS.left=(Math.sin(R*x1+i*x2+x3)*x4+x5)+"px"; DIS.top=(Math.cos(R*y1+i*y2+y3)*y4+y5)+"px"}R++}setInterval('A()',5); void(0);

6. You can navigate to other sites and try it there too

7. Even better in sites with tons of pics

8. Don't go around sites just copying and pasting javascript code in your address bar! =oP

Wednesday, October 25, 2006

Escape characters to use reserved words as variable names in .NET

This post is a follow up to Jean-Paul's article: Naming variables using the variable type name (useless tip #1), from the MSDN documentation we get this (at the top of the C# keywords section)

Keywords are predefined reserved identifiers that have special meanings to the compiler. They cannot be used as identifiers in your program unless they include @ as a prefix. For example, @if is a legal identifier but if is not because it is a keyword.

.NET solved what was one of the biggest problems in the development area, which was seamless language interaction (because now every language compiles down to Intermediate Language).

Today in .NET you can write code in any .NET language and use it in any other .NET language; however, this does bring one issue, which is that reserved words in one language may not mean anything in other language, for example you might be programming in C# and you could call a variable begin, which in Delphi is a reserved word, and so when they used your C# code from Delphi they couldn't use it; to solve this problem, languages should (for their own good) implement some kind of escape character that allows you to use reserved words as variable names in case you are using code that was written in another language and they declared a variable name with the name of a reserved word in the language you are using

in C# you use the @ prefix

string @while = "something"
Console.WriteLine(@while);

in Delphi you use the & prefix

&begin:Integer;
begin
&begin := 10;
Console.WriteLine(&begin);

in VB.NET you use brackets to delimit the keyword

Dim [Dim] = 20
Console.WriteLine([Dim])

let me know if you know the escape character for other .NET languages

p.s. just noticed Jeff calls them escaped identifiers


kick it on DotNetKicks.com

Monday, October 23, 2006

How to: Execute (another's class) private methods

Applies to C# (Tested using C# 2.0)

The access modifier private is the most restrictive one, allowing access only to the containing type

Every once in a while we want to access a private method in some class that we don't have source code for (BCL anyone?); usually we shouldn't have to do that, but in case you need it for whatever reason, here's a way of doing it:

Lets create a test class to be used as our example:

public class TestClass {
public TestClass() {
}
private void HiddenMethod() {
Console.WriteLine("secret method, should only be called from the containing class itself");
}
private string HiddenMethodWithParams(string firstName, int age) {
return string.Format("hello {0}, you are {1} years old", firstName, age);
}
}

Basically this class is useless, because it doesn't expose any public methods... unless we had access to the private methods (okay, it's still useless, but this is just my lame example)


Now, let's see how we can access those private methods

TestClass tc = new TestClass();
Type testClaseType = typeof(TestClass);

MethodInfo hiddenMethod =
testClaseType.GetMethod("HiddenMethod",
BindingFlags.NonPublic | BindingFlags.Instance);
hiddenMethod.Invoke(tc, null);

MethodInfo hiddenMethodWithParams =
testClaseType.GetMethod("HiddenMethodWithParams",
BindingFlags.NonPublic | BindingFlags.Instance,
null, new Type[2] { typeof(string), typeof(int) }, null);
string result = (string)hiddenMethodWithParams.Invoke(tc, new object[2] { "Eber", 25 });
Console.WriteLine("result: "+ result);

Let's go in detail:



  1. 1- The first line just creates an instance (tc) of the class (TestClass) we're interested in (because it contain those precious private methods that we want)
  2. 2- The second line gets the type of the class, in this case it would be TestClass, this variable (testClassType) is used later on to query that class about it's methods.
  3. 3- Then it gets interesting, we acquire a "pointer" to the "hiddenMethod" private method and store it in the hiddenMethod variable; we do this by querying the testClassType variable, passing the name of the method; the parameter BindingFlags.NonPublic means you want a member which is not public (private in this case) and BindingFlags.Instance means you want an instance method (as opposed to an static one), remember that static methods don't get executed from an instance, but are called directly from the class.
  4. 4- Now that we have a pointer to the method we just need to call it, all we have to do is call the Invoke method of our hiddenMethod variable, we pass tc as a parameter, this is the instance on which we are executing the method (tc is the instance we created on the first line)

That's pretty much all we have to do, but of course a method that doesn't take any parameters and doesn't return anything is not very useful, so I included an example of calling a more complex method, one that takes parameters and returns something.


We just have to change a few things to make it work:


On step 3, where we get the pointer to the method, we need to pass information about the method's parameter types, this information is passed in an array, if you go to the top and look at the TestClass, you'll see that the method HiddenMethodWithParams takes 2 parameters, a string and an int, now let's see how we specify that:


new Type[2] { typeof(string), typeof(int) }


Which means: 2 parameters, the first one is a string, the second an int


You could (of course) pass any type of parameter here


Now we have the pointer to the method we want, but this method returns something, so we'll have to change the way we call it:


string result = (string)hiddenMethodWithParams.Invoke(tc, new object[2] { "Eber", 25 });


Here we create a variable to store the result, then we call the method, casting it's result to the type we know it returns (a string), the parameter tc remains the same, remember this is the instance on which we are calling the method, last we need to pass the parameters to the function, the way of passing the parameters is very similar to the way we specified their types


new object[2] { "Eber", 25 }


Which translates to: 2 parameters, the first one is "Eber", the second:25


That's it! try not to abuse this technique, full source can be found here


side node: while running Live Writer spell checking it suggested that I should call my test Class Testicles instead of TestClass


kick it on DotNetKicks.com

Get first and last elements of an Enum

This article applies to C# 2.0

From time to time (not very often) we have an enumeration and we want certain parameter (perhaps coming from a db) to be within the bounds of our enumeration (remember that it's legal to cast any integer value into an Enum, even if the value is out of the range defined in your Enum), most of the code I have seen just checks if such value is less than the last element in the enum, something like:

enum TestEnum {

  Enum1 = 1, Enum2 = 2, Enum3 = 3;

}

TestEnum myValue; //this might be coming as a parameter to a function

if (myValue > TestEnum.Enum3) //some code to handle this situation

and each time you have to update the enumeration, you have to take care of changing this part of the code.

This function returns the first and last elements (not int values) of an Enum, I wrote it using generics so you can reuse it with any Enum type, you could modify this to be specific to your enum and the function could be used in C# 1.0 (VS2003), the use of the function is probably rare, but anyway, here it is

public void GetLowHighFromEnum<T>(out T lowElement, out T highElement) {
if (!typeof(T).IsSubclassOf(typeof(Enum))) //make sure we got an Enum
throw new ArgumentException("parameterized type should be Enum");
T[] values = (T[])Enum.GetValues(typeof(T));
lowElement = values[0];
highElement = values[values.Length - 1];
}

To use it, it would be something like:

TestEnum te1, te2;
GetLowHighFromEnum<TestEnum>(out te1, out te2);
Console.WriteLine(te1.ToString());
Console.WriteLine(te2.ToString());

Saturday, October 21, 2006

It is legal to cast any integer value into an Enum even if the value is out of the range defined in your Enum

I've been researching Enums recently and have found some very interesting facts about them, for example:

It is legal to cast any integer value into an enum even if the value is not defined in the enum.

this is valid:

public enum TestEnum {
Enum1 = 1,
Enum2 = 2,
Enum3 = 3
}

...


TestEnum t = (TestEnum)10; //WTF?
Console.Write(t.ToString());
Console.Read();


Consider when the value comes from another source, such as a database


If you are dealing with Enums, you should read this article by Krzysztof Cwalina, it is a very complete reference / guideline for Enums; then when you get into Nullable Enums it gets even more interesting, I'll post a few things I'm doing with Enums

Wednesday, October 18, 2006

using the mouse: did you know...?

did you know that the middle button serves the purpose of closing windows in most tabbed-document applications? (you have to click on the tab)

for example all the new browsers: IE7, Firefox, Flock, Opera, etc, implement this; but also Visual Studio, Some Notepad replacements, MSN Messenger, etc, most of the tabbed-documents applications implement this funcionality

also, on browsers, "middle clicking" on a link opens the link on a new tab

Monday, October 16, 2006

quest for a better CAPTCHA

Recently, Geoff got concerned with SPAM and the current alternatives to try to avoid it, ever since he has been working on a simpler approach (for the user) where he provides pictures instead of text, and you have to click on a few of the pictures, depending on the given instructions; while the idea is original, and it does make it easier on the user, I can see a few issues with the approach

  • images have to be downloaded to all your readers (bandwidth)
  • you have to have a considerable amount of pictures to make this usable (and more bandwidth problems associated with that)
  • Each implementation of this would have to have it's own set of pictures and rules associated with them (kinda hardcoded)
  • it's kinda big

This, however, has given me another idea, why don't we combine regular text with Geoff's idea?

we could have something like:

click on even numbers: 123641

click on mathematical symbols: 123+45/6*21

click on uppercase characters 1A654abPK

etc, the font of course can be different (and bigger), the advantages are:

  • very small
  • infinite number of CAPTCHAS can be generated programmatically
  • it's readable
  • taking some precautions it can be very clear and simple what the user needs to do (some times I can't tell if Geoff is smiling or he's angry =o( )

am I missing something, or did I just come up with the greatest idea against SPAM? =o)

if you still like Geoff's idea, I think at least the images (and questions associated with that) could be generated programmatically, e.g. lines in different angles, circles, triangles, etc, that by itself would solve most of the problems I see with Geoff's approach

anyway, time to go to sleep

Thursday, October 12, 2006

careful with commas in your SQL statements

yesterday we had a bug that was something like:

select field1, field2, field3
field4, field5
from SomeTable
where field1 = 'someValue'

can you spot the bug?

the query runs just fine, but it didn't output the desired results

the problem is that it's missing a comma between field3 and field4, thus is like saying:

field1, field2, field3 as field4, field5

which, you can imagine; you are expecting certain data (and data type) on that field on you get something else and you mis a field

this syntax I believe is Ansi 92 SQL standard, so you can get the same problem on MSSQL, MySQL, Oracle, etc (our code ran fine in MySQL and the bug came up in Oracle because we had different data)

Wednesday, October 11, 2006

Tour Guadalajara - Aguascalientes

I will be traveling on vacations to Guadalajara & Aguascalientes (Mexico) from the 28 of Oct - 6 Nov (I might go to Mexico city a couple of days), if anyone is interested in meeting there and have a geek dinner, talk about development and geek crap, leave me a message

Tuesday, October 10, 2006

Filemon is to files what ____ is to debugging

if you answered Debug View, you get a star, if you don't know about this gem, let me give you a little introduction:

DebugView is an application that lets you monitor debug output on your local system, or any computer on the network that you can reach via TCP/IP. It is capable of displaying both kernel-mode and Win32 debug output, so you don't need a debugger to catch the debug output your applications or device drivers generate, nor do you need to modify your applications or drivers to use non-standard debug output APIs.

DebugView works on Windows 95, 98, Me, 2000, XP, Windows Server 2003, Windows for x64 processors and Windows Vista.

Basically, on your code (pretty much any language that uses the standard windows libraries to output debug), for example C#, you just put something like:

Debug.WriteLine("this is freaking awesome");

you run Debug View, then you run your program (web app or whatever it is you are debugging) and that's it! you get the output in a window much like filemon shows the file activity

brought to you from the guy who doesn't see problems, only solutions

Monday, October 09, 2006

testing ThinkStar insert code plugin

I have not been happy with the plugins to insert code, my biggest problem is that they don't show up in the RSS feed, let's try this one (in german, but you can find the download link)
 
.
throw new Exception();//    TODO: Delete Me! For Testing Purposes

and, as for the code, we had to put this to show the logging capabilibites of our application, because we coulnd't get the app to throw any exceptions =o)

Friday, October 06, 2006

Using generics and anonymous delegates to populate a drop down list from a dictionary

but mostly just testing Douglas Stockwell's plugin
    private void LoadDropDownListFromDictionary<TKey, TValue>(DropDownList ddl,
IDictionary<TKey, TValue> dict,
GetNameDelegate<TValue> getName,
ConditionDelegate<TKey> getCondition)
{
foreach (KeyValuePair<TKey, TValue> pair in dict) {
if ((getCondition == null) || (getCondition(pair.Key)))
ddl.Items.Add(new ListItem(getName(pair.Value), pair.Key.ToString()));
}
}
and yes, you can also databind it directly using the dropdownlist.DataSource,
DataTextField and DataValueField

Tuesday, October 03, 2006

Doing the Filemon

I was looking for the some video where they show the filemon tool (I think I saw it on the hanselminutes) to pass it to some co-worker, and I found this instead, I was curious to see what he was doing with the Filemon or what was the deal, it got me laughing instead

Saturday, September 30, 2006

Game programming from scratch

In programming there are several different... I guess I could call them branches, each requiring very different skills, to name a few we have

  • Operating System's development
  • Device programming
  • Device drivers
  • Anti-virus
  • Virus writing
  • Large Frameworks (I'm talking about .NET for example)
  • Game programming

Event just in Windows you could talk about

  • Native win32
  • Managed
  • windows services
  • web services
  • web programming
  • etc...

Game programming is one of those branches that requires a lot more knowledge on quite a few different topics than (and usually in addition to) regular traditional programming.

Game programming is something that I have always been interested in, the most I've done however, are a couple text based games and a domino game that can be played over a LAN; as part of my interests I have studied OpenGL and DirectX, I even wrote a few beginner articles on Delphi and OpenGL.

I have read quite a bit about game programming in general, enough to know that your first game should be something simple, most people trying game programming for the first time attempt to create something big like a 3D first person shooter, most people however, fail.

The guys who have been there and know game programming recommend you create something like a Tetris for your first game, even though this is a really simple game, it's got all the elements of any game

  • input
  • logic
  • animation
  • levels
  • a game loop (every game has a game loop)

Other good choices for your first game could be an steroids, bricks, pac-man. If you need more ideas you could visit sites like miniclip, they have hundreds of flash games, you can even chose to write a simpler version of a game you chose, the whole point is that you should finish it, and once you finish it, maybe you extend it, but you would have already finished v1.0 of your first game and that is really important.

These days starting a game "from scratch" is really far from what it used to be just a few years ago, where you had to create everything, maybe even your own format and format loader, and every single pixel that was drawn you had to write code for that, years have gone and now we have standard formats for models, sounds, graphics, etc. and most importantly we have plenty of frameworks to build your game on top of them.

One of the latest and greatest frameworks to create games is XNA; you can think of XNA for game programming pretty much like Visual Studio for programming in C#, it allows you to focus on the actual game (theme, logic, etc), giving you all the functions ready to be used to do most of the drawing stuff, one of the cool things about XNA is that it will allow you to run your own games in your XBox 360, it doesn't get much better than that

A couple of friends and I have decided to start writing games just for fun, we will probably start with a simple pac-man, although we'll plan on making it extensible, we'll start with something really simple.

A rough idea of what we're shooting for if we go for the pac-man would be:

  • Single world
  • Single level
  • one type of ghost
  • we'll most likely create our own graphics in Paint and create our own sounds.

points of extensibility could be

  • plug-in model to create new ghosts
  • plug-in model to create new worlds and levels

as simple as that is, it allows you to extend as much as you can, however, we have to get there first.

I will blog about all my experiences (and source code) creating this first game, I'm really hoping not to fail as many have before. Just as many guys before me, I hope to, if not help, at least inspire other people to start in the wonderful art of game programming

If you want to join me, you could start by downloading XNA and Visual Studio 2005 Express Edition, you also need to download The Wizard, which is a simple animation that will teach you most of the basics of what you need to create your first game and will help you get familiar with XNA.

Until next time

Thursday, September 28, 2006

google reader finally has a decent user interface

I have been using google reader for a couple months now, but to be honest it had a horrible user interface, until just now, it finally groups the feeds by category in folders and shows you counts of unread items... just like a normal RSS reader

this is probably all over the news now, but I just logged in to check my blogs and saw the new interface, it wasn't there this morning... anyway, check it out

Monday, September 25, 2006

Simple Generic Factory

Last time I presented you with simple factory pattern using dictionaries of methods and talked about Steven's (much more elegant and generic) implementation. I kept playing with Steven's code, whilst the dynamic code generation is pretty cool I kept thinking there was an easier way to accomplish the same thing; I finally came up with a much shorter version, here it is:

public static class SimpleStaticGenericFactory<TKey, TBaseType> where TBaseType : class {
public delegate TBaseType BaseTypeInvoker();
private static Dictionary<TKey, BaseTypeInvoker> methods =
new Dictionary<TKey, BaseTypeInvoker>();
public static void Add(TKey key, BaseTypeInvoker instantiatorMethod) {
if (!methods.ContainsKey(key))
methods.Add(key, instantiatorMethod);
}
public static void CreateInstance(TKey key) {
if (methods.ContainsKey(key))
methods[key]();
else //what would you like to do in this case?
throw new ArgumentException(string.Format("{0} not found", key));
}
}

that's it!, or if you prefer the non-static version:

public class SimpleGenericFactory<TKey, TBaseType> where TBaseType : class {
public delegate TBaseType BaseTypeInvoker();
private Dictionary<TKey, BaseTypeInvoker> methods =
new Dictionary<TKey, BaseTypeInvoker>();
public void Add(TKey key, BaseTypeInvoker instantiatorMethod) {
if (!methods.ContainsKey(key))
methods.Add(key, instantiatorMethod);
}
public void CreateInstance(TKey key) {
if (methods.ContainsKey(key))
methods[key]();
else //what would you like to do in this case?
throw new ArgumentException(string.Format("{0} not found", key));
}
}

We *don't really need* the CreateInstance method there, we could call the method directly if the dictionary was public, but it wouldn't be good to give them access to the dictionary. Using the reports from our last example, we could use it like:

SimpleStaticGenericFactory<string, BaseReport>.Add("report1", delegate() { return new Report1(); });
SimpleStaticGenericFactory<string, BaseReport>.Add("report2", delegate() { return new Report2(); });
SimpleStaticGenericFactory<string, BaseReport>.CreateInstance("report1");

or using the non-static version:

SimpleGenericFactory<string, BaseReport> reports1 = 
new SimpleGenericFactory<string, BaseReport>();
reports1.Add("report1", delegate() { return new Report1(); });
reports1.Add("report2", delegate() { return new Report2(); });
reports1.CreateInstance("report1");

nice and simple, I'll put an example together for a plug-in model using this factory


kick it on DotNetKicks.com

Saturday, September 23, 2006

Simple factory pattern using Dictionaries of methods

I have been talking about arrays of methods, dictionaries of methods, how both techniques are very similar in implementation, when you can use either one, and a practical implementation of the simple factory pattern using arrays of methods. Today I'll show you the implementation of the simple factory pattern using dictionaries of methods and then we'll move into more interesting things, Steven posted an implementation of the same pattern that leaves my implementation in the dust, I'm still posting my code here as another example of how you can use dictionaries of methods. 

using ReportCreatorDictionary = Dictionary<string, ReportCreatorDelegate>;
//this is our base product
abstract class BaseReport {
public BaseReport() {
Console.WriteLine("Base Report Created");
}
public abstract void Execute();
}//product 1
class Report1 : BaseReport {
public Report1():base() {
Console.WriteLine("Report1 created");
}
public override void Execute() {
Console.WriteLine("Report1");
}
}//product 2
class Report2 : BaseReport {
public Report2():base() {
Console.WriteLine("Report2 created");
}
public override void Execute() {
Console.WriteLine("Report2");
}
}

delegate BaseReport ReportCreatorDelegate();
//this is the actual factory
class ReportGenerator {

static BaseReport CreateReport1() {
return new Report1();
}

static BaseReport CreateReport2() {
return new Report2();
}

static ReportCreatorDictionary reports;

static ReportGenerator() {
reports = new ReportCreatorDictionary();
reports.Add("Report1", new ReportCreatorDelegate(CreateReport1));
reports.Add("Report2", new ReportCreatorDelegate(CreateReport2));
}

public static BaseReport Execute(string reportType) {
return reports[reportType]();
}
}

and the way to use it:

BaseReport report1 = ReportGenerator.Execute("Report1");
report1.Execute();

BaseReport report2 = ReportGenerator.Execute("Report2");
report2.Execute();

of course the choice of the report to be executed can come from anywhere (drop down list, link on a web page, configuration, etc)


The problem with this implementation, as Steven points out, is that you have to change the factory every time you add a new product to the factory and is not flexible enough to create (for example) a plug-in model, because all the types are required to be known at compile time; and if you need a factory for another product you have write a new factory (duh!, you might think). Steve's implementation is a Generic factory that can be re-used with any other types (products); no need to write the factory, you just add the products to it and is ready to be used, go check it out, is definitely worth reading.


Steve's code has given me another idea, I'll see if it actually works the way I have pictured it and then blog about it


for now here's the code for the dictionaries of methods and this example of the factory; as always, play with it, learn from it, improve it


kick it on DotNetKicks.com

Friday, September 22, 2006

IE "Blog this" integrates with Live Writer

a few days ago I was reading on Geoff's blog that he became a Live Writer Junky and I commented that I just missed the "blog this" and "send to web snippets" features from Flock; well, Geoff wrote an extension for IE that adds this functionality and allows you to blog in Live Writer kinda the way Flock does it, but of course you get all the niceties (is this a word?) of Live Writer

that also led me to learn something new, I didn't know it was so easy to create an extension for IE, just using javascript and some registry keys, check it out

Thursday, September 21, 2006

Basic good practices

I've been kinda busy lately doing a lot of refactoring, I hope to be back to post about C# interesting things like generics and patterns soon

meanwhile, I've been catching up reading my blogs, I got to this post from Jeremy Miller, "The Will to be good", there are a few points that I have always taken to heart:

  1. Don't tolerate bad code. 
  2. Don't write code on top of bad code.
  3. Fix a broken build
  4. The "design hat" never comes off.
  5. Does quality even matter?. Absolutely

For me these things are more basic than even testing, if you follow these simple guidelines your tests will run smoothly

I don't tolerate bad code and/or developers who write sloppy code, I don't even tolerate to have warnings in my code

You will always find people in some teams who are not very good at these basic things (and I'm not talking about my current team, in case they are reading this), and you have to learn how to deal with these people, if you are the team lead that's part of your job, you have to show them better techniques, even though I know is hard, specially if you are younger than them; if you are not the team lead it gets even harder, but all you can do is be an example, if you follow those practices you will be a better developer than one that doesn't, and people will see that and start listening to you at some point.

Managers may get scared when they hear you are refactoring like mad, but that shouldn't stop you from doing so (you might even have to do it after work hours), after all you are just making life easier for you and your team

Friday, September 15, 2006

Wasabi on Wails

People rewriting their stuff in this new cool framework, what are you waiting for?

JJJ

smart-er Rootkits in Codecs

I'm afraid this is going to bite a LOT of people

You’re surfing the web, and you find a video that you really want to watch, (no, not one of “those” videos… well, not necessarily anyway), but it says you have to install a codec. Codec stands for compressor/ decompressor and is used to make otherwise huge video files into a more manageable size. You install the codec, and maybe you see the video, and maybe you don’t, but guess what? You’ve been rootkitted! Now, on one level, that’s just the classic bait and switch/ trojan horse scenario, but the _details_ are quite interesting.

be careful out there

Wednesday, September 13, 2006

photoshop amusement

truly amazing what some people can do with Photoshop (click on the picture to see a bunch more)


Tuesday, September 12, 2006

Incremental search in Internet Explorer "a la Firefox"

In case you haven't seen this yet (and if you use Internet Explorer for whatever reason), you can now have the (very requested) feature of finding text as you type in IE, almost like in Firefox

Find as you type

Dictionaries of methods in C#

This article is a follow up of my previous article arrays of methods in C#, as noted by some of the commenters, it is possible to implement this technique using dictionaries, Steven even (Steven even... kinda funny... anyway, where was I? oh ok) posted a comment with the full implementation of my code using dictionaries, I just wanted to hightlight some of the differences and perhaps give you a hint on when to use either one (although it should be obvious, but I've learnt that there is no such thing as obvious)

Since the dictionaries implement a <Key, Value> way of storing stuff, you can store an int or a string, or any other type as the key as long as you don't have duplicated entries, and on the value you can store the pointer to the method you want to execute, when using arrays you are limited to use types that can be converted to integers for the index, with dictionaries you could use other types as the index.

let's see the last example and how it changes, the changes -as you will see- are pretty minimal to switch between the two

- The delegate declaration doesn't change

- now instead of an array, we have a dictionary, it looks something like this:

Dictionary<int, AddStringDelegate> addStringMethods;

- The methods declaration stay the same


- Adding the methods to our dictionary is just a little bit different:

addStringMethods = new Dictionary<int, AddStringDelegate>(4);
addStringMethods.Add((int)StringType.Type1, new AddStringDelegate(AddStringType1));
addStringMethods.Add((int)StringType.Type2, new AddStringDelegate(AddStringType2));
addStringMethods.Add((int)StringType.Type3, new AddStringDelegate(AddStringType3));
addStringMethods.Add((int)StringType.Type4, new AddStringDelegate(AddStringType4));

- The implementation to use the methods remains exactly the same

public void AddString(string someValue, StringType stringType) {
addStringMethods[(int)stringType](someValue);
}

We're done! so we just had to change a couple places and we are now using dictionaries of methods instead of arrays.


So when do I use dictionaries over arrays? basically, when you need it, arrays are a lot more simple and lightweight, dictionaries add weight but give you a lot more flexibility, for example if you want to use a string as the index to access your method, then the dictionary is the way to go; dictionaries also allow you to add/remove items from it, I don't know that it would be a good idea to apply that in this case, but you can do it. If you can get an integer index I would use the array instead, you don't really need the dictionary in that case.


If no one (out of my 3 readers J) beats me to it, I'll run some tests using both approaches and see if there is any relevant difference in speed and I'll post the results here. If you do the tests, and you blog about it, and I find out, I'll put a link here just as a follow up to this


Here's the full code, play with it, break it, expand it, make it better

class FileGeneratorBase {

Dictionary<int, AddStringDelegate> addStringMethods;

public FileGeneratorBase() {
addStringMethods = new Dictionary<int, AddStringDelegate>(4);
addStringMethods.Add((int)StringType.Type1, new AddStringDelegate(AddStringType1));
addStringMethods.Add((int)StringType.Type2, new AddStringDelegate(AddStringType2));
addStringMethods.Add((int)StringType.Type3, new AddStringDelegate(AddStringType3));
addStringMethods.Add((int)StringType.Type4, new AddStringDelegate(AddStringType4));
}

public void AddString(string someValue, StringType stringType) {
addStringMethods[(int)stringType](someValue);
}
void AddStringType1(string someValue) {
OutputText(string.Format("String Type 1: {0}", someValue));
}
void AddStringType2(string someValue) {
OutputText(string.Format("String Type 2: {0}", someValue));
}
void AddStringType3(string someValue) {
OutputText(string.Format("String Type 3: {0}", someValue));
}
void AddStringType4(string someValue) {
OutputText(string.Format("String Type 4: {0}", someValue));
}
void OutputText(string someValue) {
Console.WriteLine(someValue);
}
}

class Program {
static void Main(string[] args) {
//*** Arrays of methods demo
FileGeneratorBase fg = new FileGeneratorBase();
fg.AddString("some value", StringType.Type1);
fg.AddString("some other value", StringType.Type2);
fg.AddString("one last value", StringType.Type3);
fg.AddString("testing out of bounds", StringType.Type4);
Console.ReadLine();
}
}

on my next article I'll show you the implementation of this technique applied to the simple factory pattern just to close the loop.

Friday, September 08, 2006

Simple factory pattern made simpler

A Simple Factory pattern returns an instance of one of several possible classes depending on the data provided to it.

Last week I talked about a technique that allows you to reduce (and effectively reuse) code when you have a pattern of 2..n values, where for each value you want to execute a different method with the same signature

if (someValue == SomeEnum.Type1)
Method1("value 1");
else if (someValue == SomeEnum.Type2)
Method2("value 2");
else if (someValue == SomeEnum.Type2)
Method3("value 3");

while the method is valuable by itself, there is a pattern where it fits perfectly, this is the simple factory method; let's start with a reports example.

Suppose we have a Base Report class, and two implementations of it:

abstract class BaseReport {
public BaseReport() {
Console.WriteLine("Base Report Created");
}
public abstract void Execute();
}
class Report1 : BaseReport {
public Report1():base() {
Console.WriteLine("Report1 created");
}
public override void Execute() {
Console.WriteLine("Report1");
}
}
class Report2 : BaseReport {
public Report2():base() {
Console.WriteLine("Report2 created");
}
public override void Execute() {
Console.WriteLine("Report2");
}
}

enum ReportType {
Report1,
Report2
}
To use the arrays of methods, we have to declare our delegate to instantiate the reports:
delegate BaseReport ReportCreatorDelegate();
Then we have our factory class that contains:

  • An array of methods

  • a method to instantiate each report

  • The method to execute the requested report, depending on the parameters
class ReportGenerator {
static BaseReport CreateReport1() {
return new Report1();
}
static BaseReport CreateReport2() {
return new Report2();
}
static ReportCreatorDelegate[] reports;
static ReportGenerator() {
reports = new ReportCreatorDelegate[2];
reports[0] = new ReportCreatorDelegate(CreateReport1);
reports[1] = new ReportCreatorDelegate(CreateReport2);
}
public static BaseReport Execute(ReportType reportType) {
return reports[(int)reportType]();
}
}

Then here's how we use this code:

BaseReport report1 = ReportGenerator.Execute(ReportType.Report1);
report1.Execute();

BaseReport report2 = ReportGenerator.Execute(ReportType.Report2);
report2.Execute();
Console.ReadLine();
Update: Pablo commented "the fact that calling the factory with the type you want to create is kinda the same as creating it yourself", it is true, I could've just created an instance directly my self there, but this was just a bad example from my part, that value could come from a drop down select list, from a configuration file, etc, I just did a bad job showing you how you could use the code.

This particular example is very light weight and works great to implement this simple pattern, but it has the limitation that it works only for values that can be converted to integerAyende and Steven pointed out that the same technique can be implemented using Dictionaries, this would allow us to have other types as the index of our collection of methodsOn my next posts I'll show you this technique, using Dictionaries of methods

You can find the full source code for this and my previous example here

How to install multiple personalities of Turbo Explorer

Andy has created a program that allows you to install multiple personalities of the Turbo Explorer products (since by default you can only install one)

The steps, according to Andy are really simple:

How to install
==============
1. Install the first Turbo Explorer personality with the installer
that is included in the Turbo Explorer download.
2. Extract the next Turbo Explorer personality installer to a directory
of you choice.
3. Start the TurboMerger.exe and select the directory where you have
extracted the next Turbo Explorer personality installer. Press the
"Install" button. In the InstallShield installer do not change the
directories. Doing this will destroy the Turbo Explorer installation.
4. Proceed with step 2. until you have installed all personalities you
want.

if you are one of the people who downloaded these products, this is definitely a must have

where Delphi stands right now

Daniel Wichnewski just posted the number of downloads for the turbo explorer products, a few thousand downloads, these are the most significant numbers:

turbocpp.exe: 464
turbocpp_de.exe: 348

turbocsharp.exe: 232
turbocsharp_de.exe: 226

turbodelphi.exe: 766
turbodelphi_de.exe: 851

turbodelphi4net.exe: 200
turbodelphi4net_de.exe: 266

Delphi for .NET doesn't seem to be very popular

Wednesday, September 06, 2006

XML Notepad

going through my blogs I found this little tool

XML Notepad 2006 provides a simple intuitive user interface for browsing and editing XML documents.

definitely one more to have in the toolbox

Finding great developers

Joel talks about his experiences hiring developers and how difficult it is to get the great ones, his main point is that the great developers are already taken and that most of the resumes you get are from the pretty bad developers 

The great software developers, indeed, the best people in every field, are quite simply never on the market.

The average great software developer will apply for, total, maybe, four jobs in their entire career.

I guess I'm on a good path, I'm still on my first job J

I've had many discussions with co-workers about this same topic, while I pretty much agree with everything Joel says on this post, there's some people who think that is not that hard to get good developers

I'm of the idea that from a generation of (so-called) computer scientists you get one or two good developers (the great ones are a lot more rare than that)

Joel then goes on describing how you could get some of those great developers:

  • Go to the mountain
  • Internships
  • Build your own community*
  • That pretty much leaves out medium and small companies, there's no way they could afford to do things like that

    He closes the article by listing some problems you might face if you use employee referrals

    Unfortunately for me I haven't personally met anyone that I consider a great developer, I wish I had because I would've learnt so much more and faster; I have met very few that I consider good developers, but I guess is all up to your own standards, it's about how passionate you are about developing, it's about how good you are

    Ayende pictures developing as an art, that describes it fairly well for me, I believe a talent is required, and as such, you are born with it, sure you can learn it, but you won't be anywhere near as good as someone who has the talent

    This blog post doesn't make justice to Joel's article, Joel has been on the business for quite a while, he does know a thing or two about developers J, go check his article

    The Turbos are back

    Not the latest and greatest news, I'm just catching up with my blogs; the guys at "DevCo" have been working really hard and came out with free versions of the IDEs for Delphi, C++ and C#

    What does it have for you? If you are using VS for .NET 1.x, not much, if you are using .NET 2.0 there's (almost) nothing here for you, but if you still need Win32 applications, these are by far the best IDEs to create native win32 applications

     

    Please Note! Only one Turbo Explorer edition can be installed per machine, so be sure to download and install the one that's best for you!

    It's free and is the best, you can't go wrong with that

    The download page is here

    Wednesday, August 30, 2006

    Arrays of methods in C#

    How many times have you written code that goes something like this:

    if (someValue == SomeEnum.Type1)
    Method1("value 1");
    else if (someValue == SomeEnum.Type2)
    Method2("value 2");
    else if (someValue == SomeEnum.Type2)
    Method3("value 3");

    maybe you used a switch statement to accomplish the same kind of thing.


    You can see the pattern there, Method1, Method2 and Method3 all have the same signature and they get executed when the value Type1, Type2 or Type3 is passed. Wouldn't be nice if we could reduce that to a single line?


    That's exactly what arrays of methods can do for you, let's see an example, before we can use them we need to set them up


    Since all the methods share the same signature it means we can use a delegate to represent all of the methods.

    delegate void AddStringDelegate(string someValue);

    Now we can declare an array of delegates:

    AddStringDelegate[] addStringMethods;

    We will use an enumeration to access the items of the array:

    enum StringType {
    Type1,
    Type2,
    Type3,
    Type4
    }

    Then we need the actual methods declaration:

    void AddStringType1(string someValue) {
    OutputText(string.Format("String Type 1: {0}", someValue));
    }
    void AddStringType2(string someValue) {
    OutputText(string.Format("String Type 2: {0}", someValue));
    }
    void AddStringType3(string someValue) {
    OutputText(string.Format("String Type 3: {0}", someValue));
    }

    finally, on the constructor of our class, we assign the methods to the array to get our array of methods:

    addStringMethods = new AddStringDelegate[3];
    addStringMethods[(int)StringType.Type1] = new AddStringDelegate(AddStringType1);
    addStringMethods[(int)StringType.Type2] = new AddStringDelegate(AddStringType2);
    addStringMethods[(int)StringType.Type3] = new AddStringDelegate(AddStringType3);

    It's ready to be used, let's see what the implementation looks like:

    public void AddString(string someValue, StringType stringType) {
    addStringMethods[(int)stringType](someValue);
    }

    As you can see we can access the required method by converting the enumeration to an int type, our code was just reduced to 1 line; passing the desired enum type gets to our method in one shot


    I'll let you decide when you want to use this technique, I wouldn't recommend using it in a small class that gets instantiated and thrown very fast and often, but in some cases it might even be useful there


    I think it would be specially useful if we had this kind of pattern inside a singleton class where the class could potentially live a lot longer, you could do all the work to initialize your array of methods and be able to re-use it effectively


    Here's the full code for this example, on my next post I'll show you how you could use this technique to implement some kind of factory pattern or what is sometimes referred to as simple factory pattern

    class FileGeneratorBase {
    delegate void AddStringDelegate(string someValue);

    AddStringDelegate[] addStringMethods;

    public FileGeneratorBase() {
    addStringMethods = new AddStringDelegate[4];
    addStringMethods[(int)StringType.Type1] = new AddStringDelegate(AddStringType1);
    addStringMethods[(int)StringType.Type2] = new AddStringDelegate(AddStringType2);
    addStringMethods[(int)StringType.Type3] = new AddStringDelegate(AddStringType3);
    addStringMethods[(int)StringType.Type4] = new AddStringDelegate(AddStringType4);
    }

    public void AddString(string someValue, StringType stringType) {
    addStringMethods[(int)stringType](someValue);
    }
    void AddStringType1(string someValue) {
    OutputText(string.Format("String Type 1: {0}", someValue));
    }
    void AddStringType2(string someValue) {
    OutputText(string.Format("String Type 2: {0}", someValue));
    }
    void AddStringType3(string someValue) {
    OutputText(string.Format("String Type 3: {0}", someValue));
    }
    void AddStringType4(string someValue) {
    OutputText(string.Format("String Type 4: {0}", someValue));
    }
    void OutputText(string someValue) {
    Console.WriteLine(someValue);
    }
    }

    class Program {
    static void Main(string[] args) {
    FileGeneratorBase fg = new FileGeneratorBase();
    fg.AddString("some value", StringType.Type1);
    fg.AddString("some other value", StringType.Type2);
    fg.AddString("one last value", StringType.Type3);
    fg.AddString("testing out of bounds", StringType.Type4);
    Console.ReadLine();
    }
    }

    updated: To initialize the array using the same enum instead of hardcoded values of 0..4

    Monday, August 28, 2006

    Hiding generics complexity part II

    on previous articles I talked about complex generic types

    Multidimensional generics

    and how to make those types more readable by using aliases

    Hiding generics complexity

        using System.Collections.Generic;
    using FilesList = List<string>;
    using FoldersWithFiles = Dictionary<string, List<string>>;
    using ComputersWithFiles = Dictionary<string, Dictionary<string, List<string>>>;

    Here is another technique to accomplish readable code while still using generics.


    We can subclass the generics in this way:

        class FilesList2 : List<string> { }
    class FoldersWithFiles2 : Dictionary<string, List<string>> { };
    class ComputerFiles2 : Dictionary<string, Dictionary<string, List<string>>> { }
    class ComputersWithFiles2 : Dictionary<string, Dictionary<string, List<string>>> { }

    The code to use them is pretty much the same as when we were using aliased generics, but there is a little "problem", KeyValuePair is a struct and as such it doesn't support inheritance, which means we can't apply this technique to this type, so we can combine aliased types for the KeyValuePair and sub-classing for the rest


    This brings us to another point, when we have code like this:

    Console.WriteLine("List of Directories with files");
    FoldersWithFiles2 foldersWithFiles = GetFoldersWithFiles();
    foreach (FoldersWithFilesPair kv in foldersWithFiles) {
    Console.WriteLine(string.Format(" Folder: [{0}]", kv.Key));
    ListFiles((FilesList2)kv.Value);
    }

    If we want to use FoldersWithFilesPair.Value as a FilesList2 type we have to typecast it, this is because FilesList2 is a new type and FoldersWithFilesPair.Value is a List<string>; remember that C# is a type-safe language.


    Subclassing the generic types in this way can give you more benefits than simply more readable code, as any other class they can implement methods so you can assign them more specific tasks/methods that reflect more accurately their responsibility


    There is a big difference betwee using aliased generics and subclassed generics, aliased types are the exact same type, just with a different name, subclassed generics are a new name and a new type.


    This is it for now, you now have a new tool in your toolbox, as with everything else in life, don't abuse it!


    Hope to see some code where people are using these techniques


    as promissed, here is the full source code, the code is free as in LPGL