Labels

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

Thursday, May 8, 2008

Implicit vs Explicit Interface Implementation

Hi,

Have you ever noticed, while implementing an interface, .Net auto intellisense provides two options as below. The code generation for these two options differ and also the Explicit generates a problem and requires fix to avoid it. Below are the details.









Here is the code below for each of the options.

First Option: (Non Explicit)

public void InstantiateIn(Control container)

{

throw new NotImplementedException();

}

Second Option: (Explicit)

void ITemplate.InstantiateIn(Control container)

{

throw new NotImplementedException();

}

Problem with Explicit:

FxCop produces ‘Interface methods should be callable by child types’ error if we opt for the Explicit option. The explanation is as below.

· Consider a base type that Explicitly implements a public interface method.

· A type that derives from the base type can only access the inherited interface method through a reference to the current instance (this in C#) that is cast to the interface.

· Now, If the derived type re-implements (explicitly) the inherited interface method, the base implementation is no longer accessible. i.e The call through the current instance reference will invoke the derived implementation; this results in recursion and an eventual stack overflow.

Exception:

This rule does not report a violation for an explicit implementation of System.IDisposable.Dispose() when an externally visible Close() or System.IDisposable.Dispose(Boolean) method is provided.

How to Fix Violations

To fix a violation of this rule do either below.

A. Implement a new method that exposes the same functionality and is visible to derived types or

B. Change to a non-explicit implementation.

C. However, If a breaking change is acceptable, an alternative is to make the derived type sealed.

using System;

namespace DesignLibrary

{

public interface ITest

{

void SomeMethod();

}

public class ViolatingBase : ITest // Violating

{

void ITest.SomeMethod() // Explicit

{

// ...

}

}

public class FixedBase : ITest // Correct Approach (Point A)

{

void ITest.SomeMethod()

{

SomeMethod();

}

protected void SomeMethod()

{

// ...

}

}

public class FixedBase : ITest // Correct Approach (Point B)

{

public void SomeMethod()

{

SomeMethod();

}

}

sealed public class Derived : FixedBase, ITest // Correct Approach (Point C)

{

public void SomeMethod()

{

// The following would cause recursion and a stack overflow.

// ((ITest)this).SomeMethod();

// The following is unavailable if derived from ViolatingBase.

base.SomeMethod();

}

}

}

Thanks & Regards,

Arun Manglick || Senior Tech Lead

Monday, March 24, 2008

Catch All

Hi,

catch (Exception e)

{

Console.WriteLine( “An exception was thrown. Message was: “ + e.Message);

}

catch

{

Console.WriteLine(“Some other exception has occurred”); // Catch All Block

}

Note: catch (Exception e) will fire in case of .Net Exceptions and catch all fire in case of below mentioned case. There is no precedence concept here.

· This is the most general catch block of all—it doesn’t take any parameter.

· The reason this catch block is used is to catch exceptions thrown by other code that

o isn’t written in C#, or

o isn’t even managed code at all.

· It is a requirement of the C# language that only instances of classes that are derived from System.Exception can be thrown as exceptions, but other languages might not have this restriction— C++, for example, allows any variable whatsoever to be thrown as an exception.

· Although in many cases, the .NET PInvoke mechanism will trap these exceptions and convert them into .NET Exception objects, still if your code calls into libraries or assemblies that have been written in other languages, then it might find an exception thrown that is not derived from System.Exception. In such cases the catch all will work.

In an all, C# equivalent of C++ catch (…), which was a catch-all statement for any possible exception.

Thanks & Regards,

Arun Manglick || Tech Lead

Monday, December 10, 2007

Swap Myth - Value/Refrence Type

In the interview if I ask a simple question – How swap of Value and Referecne type works. Outcome is always unsatisfactory.

Here is the myth.

Suppose you have two Value types and two Reference Types. Lets try to swap them.

Value Types –

string str1 = "Hello";

string str2 = "World";

MessageBox.Show("Before Change: " + str1 + "," + str2); // Hello World

SwapMe( str1, str2);

MessageBox.Show("After Change: " + str1 + "," + str2); // Hello World [Does not works]

· The values of the parameters is passed as ‘By Value’.

· Hence swapping did not worked.

· To success, need to pass the value types By Reference using the ‘ref’ keyword.

SwapMe(ref str1, ref str2);

Reference Types –

Employee obj1 = new Employee(5);

Employee obj2 = new Employee(6);

MessageBox.Show("Before Swap: " + obj1.i.ToString() + "," + obj2.i.ToString()); // 5, 6

Swap.SwapMe(obj1, obj2);

MessageBox.Show("After Swap: " + obj1.i.ToString() + "," + obj2.i.ToString()); // 5, 6 [Does not works]

· Before we proceed, just notice that the value of the parameter is the address of the object (Pointer to the object) and not the value of object.

· The address is passed as ‘By Value’ and not ‘By Reference’. (Might be feeling strange).

· Hence swapping the address would not affect the actual addresses.

· But if you need to do this, pass it using ‘ref’.

Swap.SwapMe(ref obj1, ref obj2);

But at the same time instead of swapping if you want to change the values as below, then it will work perfectly fine without the use of ‘ref’ keyword.

Employee obj1 = new Employee(5);

Employee obj2 = new Employee(6);

MessageBox.Show("Before Swap: " + obj1.i.ToString() + "," + obj2.i.ToString()); // 5, 6

ChangeMe s(obj1, obj2);

MessageBox.Show("After Swap: " + obj1.i.ToString() + "," + obj2.i.ToString()); // 6, 5 [Does works]

· As above described value of the parameter is the address of the object (Pointer to the object) and not the value of object.

· The address is passed as ‘By Value’ and not ‘By Reference’.

· But code is dereferencing the objects and then changing its value.

· Hence it will change to the actual object, without the need of using ‘ref’.

Supporting fucntions:

// public static void SwapMe(ref Employee a, ref Employee b)

public static void SwapMe(Employee a, Employee b)

{

Employee temp;

temp = a;

a = b;

b = temp;

}

//public static void SwapMe(ref string a, ref string b)

public static void SwapMe(string a, string b)

{

string temp;

temp = a;

a = b;

b = temp;

}

public static void ChangeMe(Employee a, Employee b)

{

a.i = 55;

b.i = 66;

}

Thanks & Regards,

Arun Manglick || Tech Lead

Thursday, August 23, 2007

By FxCop

Avoid ‘out’ Parameters: By FxCop

· Using out parameters might indicate a design flaw.

· Although there are legitimate times to use out parameters, their use frequently indicates a design that does not conform to the design guidelines for managed code.

How declaring methods as ‘Static’ can increase performance? By FxCop

  • Methods which do not access instance data or call instance methods can be marked as static (Shared in VB).
  • After doing so, the compiler will emit non-virtual call sites to these members which will prevent a check at runtime for each call that insures the current object pointer is non-null.
  • This can result in a measurable performance gain for performance-sensitive code.
  • In some cases, the failure to access the current object instance represents a correctness issue.

Why Default Constructor is necessary for classes/types with only static members?

  • Instances of types that define only static members do not need to be created.
  • Many compilers will automatically add a public default constructor if no constructor is specified.
  • To prevent this, adding an empty private constructor may be required."

Static holder types should be ‘sealed’: By FxCop

  • Static holder types do not provide functionality that derived instances can extend. Inheriting from such a type indicates a flawed design.

Misc:

  • Properties that return collections should be read-only so that users cannot entirely replace the backing store.
  • Users can still modify the contents of the collection by calling relevant methods on the collection.

Exception Handling using IDisposable Interface and Dispose Method().

  • Instead of implementing only Dispose() we should implement hybrid approach.
  • Instead we should call Dispose(true), then calls GC.SuppressFinalize().

Thanks & Regards,

Arun Manglick || Tech Lead