Thursday, March 15, 2007
Yahoo! I lost my Yahoo ID!
Monday, January 08, 2007
New Blogger Woes
Saturday, November 04, 2006
Static Constructors
Static Constructors:
- Cannot have parameters
- Cannot have accessibility modifiers
- Cannot be called explicitly
- Called when the class is loaded for the first time
- Run at most once per application domain
- Can be declared for a struct as well
- Execution is triggered by when an instance of the class is created or any of the static members of the class are referenced.
- For a type is run at most once per application domain.
- That are marked extern usually specifies a DllImport attribute. Note that the keyword here is usually. The compiler doesn’t mandate you to specify one. It merely generates a warning when the following is compiled into a library or application.
- TestSC.cs(3,16): warning CS0626: Method, operator, or accessor 'A.A()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation.
public class A
{
extern static A();
static int i =2;
public static void Main() { return; }
}
Upon execution of the application it throws a TypeLoadException:
Unhandled Exception: System.TypeLoadException: Could not load type 'A' from assembly 'TestSC, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' because the method '.cctor' has no implementation (no RVA).
- When present in a class force the compiler to omit beforefieldinit declaration. The following text discusses ramifications.
Verbatim from C# Specification v.1.0: If a static constructor exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class
Program #1
//Whether field i or j would be initialized first is implementation dependant.
class A
{
static int i = 2;
}
class B
{
static int j = 5;
}
On ILDASM
.class public auto ansi beforefieldinit A
extends [mscorlib]System.Object
{
} // end of class A
Program #2
class Test
{
public static void Main()
{
System.Console.WriteLine(“j = {0}, i={1}”,B.j,A.i);
}
}
class A
{
static int i = 2;
static A() {};
}
class B
{
static int j = 5;
static B() {};
}
Since B.j is used first, field ‘j’ is guaranteed to get initialized first.
On ILDASM
.class public auto ansi A
extends [mscorlib]System.Object
{
} // end of class A
Note that there’s no beforefieldinit in the declaration:
- Can have a return statement with no expression terminating it.
Usage:
- Can be used to assign computed static fields and static readonly fields
- To make sure that the type is not marked with beforefieldinit.
Explicit Interface Implementation
//Explicit interface definition
//Be able to call an interface method ONLY through that interface
using System;
public class TestInterface : ITestInterface
{
public void Method1()
{
Console.WriteLine("Method 1 Called");
}
public void CallMethod1()
{
Method1();
}
public void CallMethod2()
{
((ITestInterface)this).Method2();
Method2();
}
///ITestInterface implementation
///Two separate implementations of methods, both explicit and implicit
//Explicit interface implementation
void ITestInterface.Method2()
{
Console.WriteLine("Method 2 Called through ITestInterface");
}
//Implicit interface implementation
public void Method2()
{
Console.WriteLine("Method 2 called through the class reference");
}
}
public class InterfaceCaller
{
public static void Main()
{
TestInterface ti = new TestInterface();
ti.CallMethod1();
ti.CallMethod2();
ti.Method2(); //No such method compiler error if implicit interface implementation is omitted.
}
}
public interface ITestInterface
{
void Method1();
void Method2();
}
Usage Scenarios:
- Explicit Interface Implementation: Restrict the method access to be through the defined interface only.
- While writing wrappers you want to restrict your team members to work only with the interface that you provide. You may have earmarked the class for refactoring later.
- Both EII & III: Provide two different implementations of the same method.
- For me personally, this is dangerous. Unless your specific situation demands that you employ this feature, it is better to leave this alone.
Thursday, October 19, 2006
TIFF support for IE
Thursday, July 20, 2006
Bluetooth for VOIP
I've been in UK for the past couple of months on a business trip. What best way to be in touch with friends if not VOIP? The glich: No built-in mic on my laptop. When I was looking for a mic, I stumbled on a Bluetooth earpiece on Amazon. I also own a Sony Ericsson w800i mobile phone that needed this for quite sometime.
Suddenly the brain wave: Why can't I use this bluetooth earpiece for VOIP? Amazon rescued me once again with the "People who bought this also bought" refrain. Belkin Bluetooth Adapter! I'm so impressed! I strongly recommend BBA for anybody who wants to use their bluetooth earpiece for VOIP. In 50 pounds, I was online in no time at all.
Tuesday, July 11, 2006
A Downloader
Tuesday, June 20, 2006
Posting in Tamil
MS Word Woes
Friday, November 18, 2005
ThreadStaticAttribute
Static methods usually do not store state in class level variables for it would be shared by all other static methods too. Unless marked ‘volatile’ two threads executing two different static methods on the same class could step on each other while assigning / reading from the variable. Also, they get to share the copy of the state. Now you could store state from a static method into “ThreadStatic” variables that only the same executing thread could see. There’s a side effect though: If you happen to use a ThreadPool. ThreadPool threads could be reused leading to state being visible when it isn’t supposed to be. Well, you could always re-initialize before exiting. The following example demonstrates that.
using System;
using System.Threading;
public class TestThreadStatic
{
int completed = 0;
public static void Main(string [] args)
{
TestThreadStatic tts = new TestThreadStatic();
tts.StartTesting();
while(tts.completed < 5)
{
Thread.Sleep(1000);
}
}
public void StartTesting()
{
Console.WriteLine("Initial value of ticks at " +
" the beginning: {0}", ticks);
for(int i = 0; i < 5; i++)
{
Console.WriteLine("Assigning work item {0}", i);
ThreadPool.QueueUserWorkItem(ExecutedOnAThread, i);
}
}
[ThreadStatic]
private static long ticks;
public void ExecutedOnAThread(object state)
{
string hashCode = Thread.CurrentThread.GetHashCode().ToString();
//Initialize only once
switch(ticks)
{
case 0:
Console.WriteLine("[{0}] A New Thread", hashCode);
ticks = -2;
break;
case -1:
Console.WriteLine("[{0}] Thread reused", hashCode);
break;
default: // if ticks is -2
Console.WriteLine("[{0}] A supposedly new " +
"thread is able to see " +
"the old value {1}",
hashCode,
ticks);
break;
}
Console.WriteLine("[{0}] Ticks at starting: {1}"
, hashCode, ticks);
ticks = DateTime.Now.Ticks;
Console.WriteLine("[{0}] Ticks at End: {1}", hashCode, ticks);
ticks = -1;
//If sleep is reduced some of the threads would be reused
Thread.Sleep(5000);
completed++;
}
}
Remember, the variable must be declared static.
Results (if running with a 5 second delay):
Initial value of ticks at the beginning: 0
Assigning work item 0
Assigning work item 1
Assigning work item 2
Assigning work item 3
Assigning work item 4
[3] A New Thread
[3] Ticks at starting: -2
[3] Ticks at End: 632691576162343750
[4] A New Thread
[4] Ticks at starting: -2
[4] Ticks at End: 632691576171406250
[5] A New Thread
[5] Ticks at starting: -2
[5] Ticks at End: 632691576176406250
[6] A New Thread
[6] Ticks at starting: -2
[6] Ticks at End: 632691576181406250
[7] A New Thread
[7] Ticks at starting: -2
[7] Ticks at End: 632691576186406250
If the delay is made 1 second:
Initial value of ticks at the beginning: 0
Assigning work item 0
Assigning work item 1
Assigning work item 2
Assigning work item 3
Assigning work item 4
[3] A New Thread
[3] Ticks at starting: -2
[3] Ticks at End: 632691595203906250
[3] Thread reused
[3] Ticks at starting: -1
[3] Ticks at End: 632691595213906250
[4] A New Thread
[4] Ticks at starting: -2
[4] Ticks at End: 632691595213906250
[5] A New Thread
[5] Ticks at starting: -2
[5] Ticks at End: 632691595218906250
[3] Thread reused
[3] Ticks at starting: -1
[3] Ticks at End: 632691595223906250
Thursday, November 17, 2005
Software as a Service
The Machines & Us
Saturday, October 16, 2004
Finding the angle between two clock hands
I had come across an URL couple of days back: http://www.karrels.org/Ed/ACM/ec97/prob_2.html where this problem of finding the angle between two clock hands was mentioned. I wrote the following C# code yesterday. This seems to work (at least for the test inputs posted on the page). Do let me know if there's a bug.
1 using System;
2
3 public class ClockProblem
4 {
5 #region Public Methods
6
7 public static void Main(string[] args)
8 {
9 if (args.Length != 1)
10 {
11 Console.WriteLine("Usage: ClockProblem 12:00");
12 return;
13 }
14 string[] time = args[0].Split(':');
15 var hr = Convert.ToInt32(time[0]);
16 var min = Convert.ToInt32(time[1]);
17 var clock = new ClockProblem();
18 Console.WriteLine(
19 "Angle between two hands at hour {0} min {1} is {2}",
20 time[0],
21 time[1],
22 clock.FindAngleBetweenHands(hr, min)
23 );
24 }
25
26 public float FindAngleBetweenHands(int hour, int minute)
27 {
28 float minuteHandAngle, hourHandAngle, angle;
29
30 //If it's 12 hour consider it 0 if(hour == 12) hour = 0;
31 //Whole clock face has 360 degrees and hence for each minute,
32 //the minute hand must move 6 degrees in clockwise direction
33 minuteHandAngle = minute * 6;
34
35 //A hour hand moves 30 degrees in an hour.
36 //Hence (hour * 30) gives us the number of degrees it moves.
37 //Also, the hour hand must move 0-30 degrees in accordance with
38 //the number of minutes the minute hand is showing.
39 //the hour hand moves 0.5f degrees per minute.
40 //Adjust hour angle accordingly.
41 hourHandAngle = (hour * 30) + (minute * 0.5f) ;
42 angle = Math.Abs(hourHandAngle - minuteHandAngle);
43
44 //The degrees must always be within 180 degrees meaning
45 //3:00 & 9:00 PM both show 90 degrees. if(angle > 180)
46 angle = 360 - angle;
47 return angle;
48 }
49
50 #endregion
51 }