Let us read some code:-
int SomeMethod()
{
int num = 1;
try
{
num = 5;
return num;
}
finally
{
num += 5;
}
}
What is the return value of SomeMethod
? Some anonymous guy asked that question in the code project forum, and it has been answered. I am writing about it here because it is interesting and subtle. One should not be surprised when people misinterpret finally. So let us take a guess, 10
(i = 5
, then incremented by 5 in the finally block).It is not the right answer; rather SomeMethod
returns 5
. Agreed that finally
is called in all cases of returning from SomeMethod but the return value is calculated when it is time to return from SomeMethod, normally or abnormally. The subtlety lies not in the way finally is executed but in the return value is calculated. So the return value (5) is decided when a return is encountered in the try block. The finally is just called for cleanup; and the num
modified there is local to SomeMethod
. So make the return value 10
, it is no use being hasty making SomeMethod
return from the finally block. Because returning from finally
is not allowed. (We will talk about it later why returning from catch
block is a bad practice and why can’t we return from finally
block). Had such modifications been done on a reference type, they would have been visible outside of SomeMethod
, although the return value may be different.
Article co-authored with Sanjeev, and published on CodeProject
Every application logs a whole bunch of diagnostic messages, primarily for (production) debugging, to the console or the standard error device or to files. There are so many other destinations where the logs can be written to. Irrespective of the destination that each application must be able to configure, the diagnostic log message and the way to generate the message is of our interest now. So we are in need of a logger class that can behave transparent to the logging destination. That should not be a problem, it would be fun to design that.
More ...This is a simple array like class for C++, which can be used as a safe wrapper for accessing a block of memory pointed by a bare pointer.
This is about a killer bug identified by our chief software engineer in our application. What was devised for ease of use and write smart code ended up in this killer defect due to improper perception. Ok, let us go!
CComPtr
is a template class in ATL designed to wrap the discrete functionality of COM object management โ AddRef
and Release
. Technically it is a smart pointer for a COM object.
I would not want to write chunks of code to spawns threads and perform many of my background tasks such as firing events, UI update etc. Instead I would use the System.Threading.ThreadPool class which serves this purpose. And a programmer who knows to use this class for such cases would also be aware that the tasks queued to the thread pool are NOT dispatched in the order they are queued. They get dispatched for execution in a haphazard fashion. More ...
Remember the Casting Restrictions we discussed a while back, let us settle that now. So we have some code like this:
object obj = i;
long l = (long)obj;
And an invalid cast exception while casting โobjโ to long. It is obvious that we are not changing the value held by obj, but just reading it. Then why restrict such casting. Let us disassemble and see what we got.
.locals init (
[0] int32 i,
[1] object obj,
[2] int64 l
)
L_0000: nop
L_0001: ldc.i4.s 100
L_0003: stloc.0
L_0004: ldloc.0
L_0005: box int32
L_000a: stloc.1
L_000b: ldloc.1
L_000c: unbox.any int64
L_0011: stloc.2
L_0012: ret
Oh, there we see something interesting - unbox
. So the C# compiler uses the unbox
instruction to retrieve the value from obj
while casting; it does not use Convert
.ToInt64
or similar mechanism. That is why the exception was thrown.
Thanks to the internet. If nobody else bothers or understands what loss of data means, you can shout it aloud here. I lost 500GB of data - every moment of my personal and professional life captured in bits and bytes.
It is a Western Digital Premium Edition external hard disk (USB/Firewire). I bought it despite my friend warning of bad sectors and hardware issues that WD is known to have. As with any story, one fine morning, I was copying some songs, pictures from my pen drive to the hard disk. All of a sudden, the hard disk and my laptop hung up. I restarted the system thinking I would make fresh start. But to my dismay, all my drives on the hard disk had vanished like dust. I tried connecting and reconnecting a few times, the drives showed up once or twice like a sick man’s last few breadths.
More ...
We all know that the runtime can detect the actual type of a System.Object
instance. The primitive data types provided by the runtime are compatible with one another for casting (assuming that we do not truncate the values). So if I have an int
, it can be cast to long
or ulong
. All that is fine. Watch this:-
interface IAppDataTypeBase
{
// Other methods
GetValue();
}
Since IAppDataTypeBase represents the mother of all types of data in my application, I have made GetValue to return the value as object (I could have used generics, that is for another day!).
More ...
Let us take a look at the following piece of code:-
public void Operate(IList iList2)
{
iList2 = new List();
iList2.Add(1);
iList2.Add(2);
iList2.Add(3);
}
public static void Main()
{
IList iList= new List();
iList.Add(10);
Operate(iList);
Console.WriteLine(iList[0].ToString());
}
Be thinking about what would the above program print to the console ? And that is what we are going to talk about in this post โ simple but subtle.
More ...
Extension Methods is an excellent feature in C# 3.0. It is a mechanism by which new methods can be exposed from an existing type (interface or class) without directly adding the method to the type. Why do we need extension methods anyway ? Ok, that is the big story of lamba and LINQ. But from a conceptual standpoint, the extension methods establish a mechanism to extend the public interface of a type. The compiler is smart enough to make the method a part of the public interface of the type. Yeah, that is what it does, and the intellisense is very cool in making us believe that. It is cleaner and easier (for the library developers and for us programmers even) to add extra functionality (methods) not provided in the type. That is the intent. And we know that was exercised extravagantly in LINQ. The IEnumerable was extended with a whole lot set of methods to aid the LINQ design. Remember the Where
, Select
etc methods on IEnumerable
.
More ...