Thursday, March 30, 2006 - 23:31

On the Personal Side: A London Update

I'm going to take a break from the tech stuff for this post, and talk more about some personal stuff.

I've been in London for 3 weeks now, and I'm getting things sorted, overall. I've got my bank account, even deposited some money into it; I've got a room in a shared flat (a nice big room, so I've got plenty of space all to myself), I've got a duvet and pillows and a picture on the wall and it's starting to feel home-like.

I've also been looking for a job - I've probably been through more interviews in the last two weeks than in my entire life. Things are coming together: I have one company that's very likely to be making an offer; I have another company interested that knows that an offer is likely going to be made, so they're packing all 3 rounds of interviews into one, tomorrow, and taking me out for lunch and basically, I think, trying to check whether they're as interested as the other company and trying to convince me that I want to work for them rather than the other company. And there's a third company who knows about these two companies, and they're interviewing me on Monday; there's a fourth company that's been promising a final round interview for about a week and a half now, but due to various factors haven't quite gotten around to setting up. And all four of these companies are quite prestigous global banks.

This is good - I'm making a good impression on my interviewers, I seem to be in demand! Certainly not a situation that would occur often in SA, where generally you have one, maybe two companies that you're interviewing with, and where all the developers (in Cape Town, at least) kind of drift around the same companies - odds are, your colleagues have either worked at or interviewed at all the same places as you. So the career opportunities are definitely looking good, and if I wasn't so exhausted by all the interviews I've had in the last few days I'd probably be a lot more excited. And tomorrow's all-day 3-rounds-in-one interview is something that I'd prefer not to face right now! although I'm sure I'll feel better after a good night's sleep. Being polite and enthusiastic and answering a million questions about your past jobs, your ideal job, what you're looking to get out of a job, as well as a bunch of tech questions, can really wear you out.

But while this is all good and very positive, it's kinda driving home the fact that I'm not just here for a month or two on holiday - I live here now. Of course I knew this before, it's not as though it's come as a surprise to me ;) But it's sinking in now, and it's a little bit scary.

So tonight I'm feeling kinda homesick - not that I had a great job in SA; not that I had a lot of friends in SA that I'm missing; not that I even had my own home in SA, since the flat I was renting was sold! But my parents are there, and my two little nieces, and my sister... and it's somewhere familiar, where I know how everything works. (Oh, and my bike. I really miss my bike.) I know I'll go back for visits, but it would be so nice just to pop home for a weekend and then come back here and carry on. Pity the flight's so long that that's infeasible.

I know that things will become familiar here too, and that I'll figure out how things work here; I'll find somewhere to have my hair cut, I'll find a good optician (although if I'm going back to SA at least once a year, I could even just carry on using my optician there! but that seems like cheating, really). And the career opportunities are great. So I tell myself (and I'm not lying to myself, it's all true - I just need to convince myself of this) that things are good here; that there's not all that much to miss back home, apart from my family (oh, and my parents' dog, who I miss as well); that when my lease on this room runs out, I'll try to rent my own entire flat, even it's just a small one; that the career outlook is far better than anything in SA; that while I can't really (and wouldn't want to) leave after only a couple months, I haven't committed to staying here for the rest of my life, and that I can always go back to SA after a couple of years. That it's just because I'm so tired from all the interviews, and tired at the thought of the long one tomorrow; that it's because I don't have internet access at the flat yet, so I can't just send email or chat to my parents whenever I like, or use SKypeOut to call them and speak to my nieces (or at least, the one old enough to talk :-), or chat to the friends that I'm used to chatting to on msn, so I'm missing those friends and just feeling a bit more isolated than usual. That I've been off work for 2 months, so it will be a bit odd and stressful going back to work, but that I'd actually go insane if I didn't work, and that working and meeting new people at work and having useful, interesting, challenging work to do was not only the point of coming here, but will also give me a sense of purpose and... I would say, distract me, but that implies just hiding the underlying problem, whereas I think it will actually solve a lot of the underlying problem. So basically, everything seems worse when you're tired, cut off from the world, and purposeless, and over the weekend I'll rest, hopefully get internet access set up, and that'll solve two of the three issues; the third is sorting itself out quite nicely, as long as I don't go getting all stressed about it!

Anyway. This post probably falls under the category of TMI, but hey, it's my blog, I get to post what I like :-) Chalk it up to the cathartic nature of blogging and move on. For now, I need to get some sleep - got a big day tomorrow. Again.

Labels:

Saturday, March 25, 2006 - 13:37

Attributes

No, I didn't really write up 2 posts today - I don't have internet access at my flat at the moment, so I've been blogging offline and then posting at a local internet cafe, which kinda sucks. Sadly, the broadband stuff arrived today, and I was really excited - but it turns out that the landlord has to set up on his laptop, I'm not really sure why, and he can only do that next Saturday. So that'll be another entire week without internet, and now I'm really disappointed. I actually spoke more to my friends here in London when I was in SA, than now that I'm actually in the same city as them. (Yeah, I could just phone them - but I really, really hate using the phone. It's like a phobia, almost).

Anway. On to the next installment of "C# for Interviews". This time, we're dealing with Attributes.

Attributes
Okay, a quick rundown on attributes. Attributes can be added to methods, classes, properties, fields - just about anything, really. It's way to add extra information about the item to the metadata of the assembly, and there's a bunch of predefined attributes (such as 'Serializable') or you can create your own.

Creating your own attributes is pretty simple; the most complex part is determining that an attribute is the best way to go. I haven't used them much; one case where they came in useful was when I had a class with a whole lot of properties, some of which were required and some of which weren't. I tagged each property with a 'Required' attribute, and when the class was populated I'd send it off to a Validator which would check the value of the 'Required' attribute, then check the value of the property to see if it was set.

So let's say we're going to do this. The first step is to create a RequiredAttribute class:


// you can set what language elements (methods, fields, etc)
// you want the attribute to be used for
[AttributeUsage(AttributeTargets.All)]
public class RequiredAttribute : System.Attribute
{
 //this should be private, and we should use properties to access it
 //but for this example, let's just make it public
 public bool Required = false;

 public RequiredAttribute(bool isRequired)
 {
  Required = isRequired;
 }
}


You get named and positional parameters, but we'll just use positional ones for this example.

Now we can tag an item with this attribute::

class MyClass
{
  [Required(true)]
  private int numRows;
}


Note that we could either use 'Required' or 'RequiredAttribute', they'll both work.

Now that we've said that numRows is required, how do we check the value of this attribute in another class? Using reflection, of course. To get a list of all the custom attributes and their values, you can do something like this:

System.Reflection.MemberInfo info = typeof(MyClass);
foreach (object attribute in info.GetCustomAttributes(true))
{
// test the type of the attribute, and deal with it appropriately
}


But this isn't quite what we want to do with the RequiredAttribute. We want to test the value for a particular field:

foreach(FieldInfo field in (typeof(MyClass)).GetFields)
{
 foreach (object attribute in field.GetCustomAttributes(true))
 {
   if (attribute is RequiredAttribute)
   {
    return ((RequiredAttribute)attribute).Required;
   }
 }
}


And it's as simple as that. You get the type of the class, get the fields (or methods, or whatever) belonging to that class, get the customattributes for each field/method/whatever, find the attribute of the correct type, then cast it and get the relevant value.

Labels:

Delegates & Events

So at my interview the day after my last post, the first question was: implement the IDispose pattern :-) So that worked out pretty well, although I did forget that the Finalize method uses the C++ Destructor syntax, and isn't a method named Finalize - which was pretty dumb.

The next question, though, was on delegates and events, and this is one that I always forget the syntax for - I tend to look it up in the MSDN when I need to use it, and then forget about it until next time. So to cement it in my head, and because it's actually quite tricky to find in the MSDN since there's so much stuff on Delegates and Events, here's a quick summary.

Delegates On Their Own

Basically, a delegate is a reference to a method. They can be used on their own, or more often, in conjunction with events. Delegates are really simple to declare:

// put this somewhere in your namespace
public delegate void MyDelegate(Object myParam);


Now if you're going to use this delegate to get one class to call methods belonging to another class (i.e. not using events), you'll need a method in that class that takes a delegate as a parameter:

// in your calling class
public void DoProcessing(MyDelegate processMethod)
{
Object obj;
// do something to populate the object
processMethod(obj);
}


The processMethod method will then be called in the context of this calling class. It will be declared in your second class:

// in your second class
public void someMethod(object obj)
{
// process the object
}


Then to actually use the delegate:

Caller.DoProcessing(new MyDelegate(c2.someMethod));


Alternatively, you can call the delegate directly:

object obj = "Hello";
MyDelegate md = new MyDelegate(obj);


So that's pretty simple. Using delegates with events is also pretty simple, provided you know how to use events:

Delegates & Events

You can declare your delegate as above, although if you're using it with events you'll probably want it to take an EventArgs parameter (or your own custom EventArgs class, which should then derive from the EventArgs base class). so let's use the MSDN example, of a list class which fires off a Changed event when an item in the list changes:


public delegate void ChangedEventHandler(object sender, EventArgs e);


Now within your class, declare an event of ChangedEventHandler type:

public event ChangedEventHandler Changed;


Now define a method that will fire off the event when an item changes:

protected virtual void OnChanged(EventArgs e)
{
if (Changed != null)
Changed(this, e);
}

And that's all there is to it, really - you'd call this OnChanged method in, say, the Add() or Delete() methods in your list, creating the EventArgs object and populating it as you require.

The only other thing you have to do is hook up the actual method that you want to handle the Changed event, which you'd do when you instantiate your list class:

private void ListChanged(object sender, EventArgs e)
{
Console.WriteLine("This is called when the event fires.");
}

// within your main method, or wherever you need this:
List list = new List();
List.Changed += new ChangedEventHandler(ListChanged);


There are some subtleties when inheriting classes with events - events themselves are not inherited, so you need to create a protected invoking method that derived classes can call, something like we did above. Better yet is to declare it as virtual, then the derived class can decide for itself whether to invoke the base event or provide one of its own.

Interestingly, events can be declared in interfaces.

If you are using a delegate which takes only an object 'sender' reference and an EventArgs class, you don't need to declare your own delegate, you can use the default .NET EventHandler delegate, which might save you a line or two of code :-)

So now that you can see how simple it is, go forth and delegate! (well, actually, don't - delegates can make your code very difficult to read and maintain. They have their place, and are sometimes essential, but use them because you need them, not just because you can!).

Update: I came across something odd today this with events. Actually, it's something I should have remembered, because I've come across it before - but I didn't. The point to remember is this: if a class subscribes to an event, and is eventually disposed, it will continue responding to the event until it's actually garbage collected. Counter-intuitive, I know, but that's how it works - so remember to unsubscribe from all events in your dispose method, otherwise you'll end up getting some odd behaviour!

Labels:

Wednesday, March 22, 2006 - 14:08

Finalize, Dispose, and London

I haven't blogged for a while, because I was busy packing up all my stuff and moving to London. But now I've been here for just over a week, have a room in a flat, and am in the middle of job interviews, and recovering from the apparently traditional adjusting-to-London's-climate cold, and I figured that it's about time to say something.

London's cool - more familiar than the States, but different enough not to be boring. I'm starting to find my way around, and at some point in the next week I'll write up my "South African's Guide to London", which just might, possibly, be mildly interesting or vaguely useful to any other South Africans coming over here, specifically ones who don't have a friend here to help them out (luckily, I did :-).

But the next couple of blog entries are going to be dev related - I haven't been coding for over a month, and my skillz are getting a bit rusty, so I've been revising stuff for the tech interviews that I've been going through. And while the MSDN is really useful, I thought it might be useful (to me, at least) to have some of the tricky stuff up here, so that it's easy (for me, at least) to find.
So without further ado, on to Dispose and Finalize.

This is a tricky subject, and I don't really know enough to debate all the ins and outs. Some people say, never implement Finalize, but from what I see in the MSDN you kinda have to - if you have unmanaged resources that you need to clean up, of course, like a database connection. Otherwise you probably shouldn't, since it is pretty slow.

The best way to go about it is to implement IDisposable. This has the advantage that anyone using your class/resource can use the 'using' clause to make sure that Dispose() is automatically called when it goes out of scope, even if an exception is thrown (sure, they could use a try-catch-finally block, but they might not).
So the MSDN-approved pattern is this (at least, in my version of the MSDN):

1. Implement a Dispose() method. This will be called if the instantiater of the class uses the using clause, or whenever they call Dispose() explicity. The Dispose() method should look something like this:
public void Dispose()
{
  Dispose(true);
  GC.SuppressFinalize(this);
}

You want to suppress the garbage collector, since you've already cleaned up everything in the class (and of course, for all the objects it contains - don't forget that bit!).

2. Implement the Dispose(bool) method:
public void Dispose(bool Disposing)
{
  if (Disposing)
  {
     // dispose the managed resources
     // e.g. if you had a Component object, call      //Component.Dispose()
}

 // regardless, clean up your unmanaged resources,
 // like handles or DB connections
}


3. Implement Finalize()
~MyClass()
{
 Dispose(false);
}

That way you cover all your bases - if the user of your class calls Dispose, it'll dispose of everything, otherwise the garbage collector will call Finalize and your unmanaged resources will be cleaned up.

You need to remember that there's no guarantee of the order in which objects will be disposed or finalized, so you shouldn't reference any external objects. And your code shouldn't throw any exceptions, even if Dispose() is called more than once - a good thing to do is have a field called something like 'isDisposed', and then check that in the beginning of your Dispose() method and do nothing if it's true. Equally, you should check the value of isDisposed in every class method, and throw an ObjectDisposedException if it has been disposed already. Also, derived classes should implement their own Dispose(bool) methods, which call that of their base class.

And that's that for Finalize and Dispose. Next time - maybe design patterns, and where to find them? Maybe. Also coming up: Structs vs Classes, Custom Attributes, using SQL in C#, and the other perennial interview favourite, Delegates (both on their own, and together with Events).

Labels: