Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Thursday, February 21, 2008

How to Control.Invoke an Anonymous Method?

Why won't Control.Invoke accept a delegate, even though it's looking for a Delegate?


This might seem like some semantic gymnastics... but when trying to compile this:

this.Invoke(delegate() { MessageBox.Show("Hello"); });


you'll get:

Argument '1': cannot convert from 'anonymous method' to 'System.Delegate'


which would suggest that a delegate is not a Delegate.

It's not exactly so - the problem is actually that the compiler does not know to what particular subtype of System.Delegate to cast/convert the anonymous method (delegate) to - and it can't create an instance of System.Delegate.

To make the code work, you have to explicitly create an instance of a particular type of a parameterless delegate returning void, e.g.:

this.Invoke(new MethodInvoker(delegate() {MessageBox.Show("Hello"); }));



see: Anonymous methods and Control.Invoke

Wednesday, February 13, 2008

XSD.exe and DebuggerStepThrough

Did you ever try to step into properties of classes generated by XSD.EXE when debugging? It doesn't work, does it? Not even on methods that you might have extended the XSD.EXE's partial classes with!


It is a common practice to generate partial classes from XSD schemas using XSD.EXE, and then extend some of them in another source file.

This all works nice and clean, but XSD.EXE is nasty and decorates all the classes it creates with the DebuggerStepThrough attribute.

That makes the debugger treat not only those parts of the classes that were created by XSD.EXE as 'nondebuggable'; you can't step into you own code (those methods in the class part authored by you), either!

Now, here are three ways to fix this:

  • run a search&replace and get rid of all the DebuggerStepThrough attributes
  • in Visual Studio, go to Tools/Options..., unfold the tree on the left-hand side of the dialog that will appear down to Debugging/General, and then uncheck the box next to 'Enable Just My Code'
    (Note that you will still have to set a breakpoint in the code marked as DebuggerStepThrough, otherwise the debugger will skip over it anyway)
  • stop using XSD.EXE :) (thanks to Marcin for this acute observation)


Well - the choice is yours :)

[see: Disable DebuggerStepThroughAttribute in code generated by xsd.exe?]

 

Tuesday, February 12, 2008

Convert an Array of Integers to an Array of Strings

This is just brilliant!


int[] ints = new int[] { 1, 2, 3, 4 };
string[] strings = Array.ConvertAll(ints, Convert.ToString);
see: Kieran Lynam's Blog

Check a String for Null or Empty

Yes, the method that .NET Framework 2.0 provides is the fastest.


You used to do it this way (I hope :):
if (s == null || s.Length == 0)

Checking the length is faster that comparing to "" or string.Empty, because the length is simply stored together with the string's content on the heap (see: Strings in .NET and C#, 'Memory usage').

.NET Framework 2.0 put the above check into a single static method of string:
if (string.IsNullOrEmpty(s))

For all the doubting Thomases ;) - this guy actually tested it:
String.Empty, null, Length, or String.IsEmptyOrNull

Friday, January 18, 2008

Calling Methods on a Null Reference???

Is it really possible to call a method of a reference pointing to null?


Take a look at this piece of code:

static void Main ( )
{
MySecondType myObject = null;
myObject = myObject.Parse("10");
}




Is it possible to make it actually run and not generate a 'null reference' exception?

Well, as long as you're using .NET 3.5 - it is! :)

The idea is to declare the Parse method as an extension method operating on objects of type MySecondType:


static class MySecondTypeExtensions
{
public static MySecondType Parse ( this MySecondType me, string text )
{
Int32 value = Int32.Parse(text);
return new MySecondType(value);
}

//...
}



As you can see - it does not matter if me points to null - since the method operates on the text parameter only!

So - nothing makes it illegal to call it on myObject - even though myObject point to null :)


The broader context is here:
Inferred Typing with Factory Methods as Extension Methods

Wednesday, October 17, 2007

LINQ - extension methods in action


As promised in one of previous posts - more about extension methods. Let's have a look at... LINQ!


You remember extension methods, whose simplest definition would be:
Extension methods are basically static methods that are callable through an instance syntax
[The Evolution Of LINQ And Its Impact On The Design Of C#]

It seems like they were introduced in C# 3.0 to make LINQ work fully.

LINQ is a language feature allowing to query collections in a SQL-like manner (SELECT statement), something like:
var locals = from c in customers
where c.ZipCode == 91822
select new { FullName = c.FirstName + “ “ +
c.LastName, HomeAddress = c.Address };


So - where are extension methods here?

Well - the sample above is actually syntactic sugar, being equivalent to:
var locals =
customers
.Where(c => c.ZipCode == 91822)
.Select(c => new { FullName = c.FirstName + “ “ + c.LastName,
HomeAddress = c.Address });

Now, let's assume customers are of type IEnumerable<Customer>. IEnumerable<T> has only one method: GetEnumerator<T>. This means that both Where and Select must be extension methods, which mix the SQL-like functionalities into all IEnumerable<T>-s!

In fact the Where method is very simple:
class EnumerableExtensions
{
public delegate T Func(A0 arg0);

public static IEnumerable Where(this IEnumerable source, Func predicate)
{
foreach (T element in source)
{
if (predicate(element)) yield return element;
}
}
}

It takes the IEnumerable<T> source parameter - which is preceded by the this keyword (so it's going to extend the IEnumerable<T> type), and the predicate delegate.
It can then use the predicate to tell whether each element in the source satisfies the "WHERE clause".
Those, that do - are put into the resulting collection of the Where method (using the yield keyword).

So, basically the following:
customers.Where(c => c.ZipCode == 91822)

will result in calling the static Where method against the customers object, with the Func<T, bool> predicate set to this anonymous method:

delegate {
if (c.ZipCode == 91822) yield return c;
}

Yep, that's what happened to the:
c => c.ZipCode == 91822
thing, which is actually a lambda expression - another syntactic sugar in C# 3.0, on which more some other time.

Sunday, October 7, 2007

Interview Questions: Constructors in C#


A good interview-type question: constructors in C#.


Here's a good one for an interview (whether you're the interviewer or the interviewee):

When declaring a constructor in the subclass, should I explicitly call the base class's constructor?
And if I don't - will the base class's constructor get called anyway?

That's basically what a discussion between my friend Marcin and me got down to...

If you've ever used Resharper (don't tell me you haven't!), you might have noticed that when you go:
class SubClass : BaseClass
{
public SubClass() : base()
{
// some code here
}
}
it will gray out base(), because it is redundant.

And it's true - because if the base constructor wasn't called, the object might not get fully initialized - and that would in a sense break the Liskov's Substitution Principle...

Actually - you do not have to "agree" for the base parameterless constructor to be invoked. You can choose a different one instead:
public SubClass() : base(5)
{
// some code here
}

However - if you look at this summary C# Constructors:
There must always be a "chain" of constructors which runs constructors all the way up the class hierarchy. Every class in the hierarchy will have a constructor invoked, although some of those constructors may not explicitly appear in the code.

All clear now, eh? ;)

Monday, October 1, 2007

Extension Methods in C# 3.0


This is actually "old stuff" today - but it is really cool: extension methods in C# 3.0 and mixins!


Ever wanted to raise a double to the power of another double without having to go like:
Math.Pow(10.343, 302.34);
?

Well, what do you say for that:
(10.343).RaiseToPower(302.34);


That would be very nice, and... it is possible, as long as:

  • you are using C# 3.0

  • you have implemented an extension method like this:

  •     public static class Powerade
    {
    public static double RaiseToPower(this double x, double y)
    {
    return Math.Pow(x, y);
    }
    }

    This is of course a quite useless example, but what extension methods are in essence is a way to implement mixins in C# 3.0: you can "mix in" some functionality to a type that is already there.

    More on mixins soon.