Welcome Guest!
Create Account | Login
Locator+ Code:

Search:
FTPOnline
Channels Conferences Resources Hot Topics Partner Sites Magazines About FTP RSS 2.0 Feed

Free Trial Issue of Visual Studio Magazine

Hidden Gems in C# 2.0 (Continued)

In C# 2.0, you can specify a more restrictive access to the set (or get) accessor. This creates much cleaner code that is easier to maintain. The access modifiers can only decrease the visibility of the property; you cannot increase the visibility using the access modifier:

public int MyValue
{
  get { return val; }
  protected set { val = value; }
}

That's a fine start, but there are a few other ways to use property accessor accessibility to write cleaner, easier-to-maintain code. First off, you can create a private property setter to use when you modify the value inside your class. That provides you, as the class author, with a single location in the code to write any validation on modifications to that value:

public int MyValue
{
  get { return val; }
  private set 
  { 
    if ( value  < 0 )
      throw new 
      ArgumentException(
       @" non-negative only" );
    val = value; 
    // Fire change event to
    // notify client code that a
    // value changed.
  }
}

This same technique applies when you implement an interface that contains a read-only property. If the interface does not contain a definition for the property setter, you can add your own, at any access level that is appropriate. However, if the interface did contain both a set and get accessor, you cannot specify different accessibility to the implementations in your class:

public interface IFoo
{
  public int MyValue
  {  get; }
}

// elsewhere:
public int MyValue
{
  get { return val; }
  // Access modifier allowed.
  // IFoo does not define a set 
  // method.
  private set 
  { 
    if ( value  < 0 )
      throw new 
      ArgumentException(
       @" non-negative only" );
    val = value; 
    // Possibly fire events to
    // notify clients of changed
    // state.
  }
}
ADVERTISEMENT

You can use the same technique with virtual and overridden property accessors. However, the accessibility must be defined in the base class, and cannot be modified in any of the derived classes.

The purpose of access modifiers on properties is to create more consistent code: A property represents a data element exported from a type. Different accessibility can be used on the set and get methods to keep the code that accesses and modifies a value more cohesive.

Friend Assemblies
Friend assemblies provide a method to allow another assembly to be granted access to the internals of a given assembly. You do this through the use of an attribute:

[assembly:InternalsVisibleTo(
  "AFriend")]

This designation provides AFriend.dll with access to all internal types, methods, fields, and properties in any type declared in the assembly where the attribute is defined.

I'd avoid using this in most production code. If you have internal types that need access from another assembly, that often indicates a poor design.

The right solution is to refactor those classes so that you can provide access only through public interfaces, or public classes. However, there is one idiom that I've found useful: unit tests for internal types and methods. I can create a separate assembly for all my unit tests, and make that assembly a friend of the target assembly. I separate all my unit tests in a second assembly, which means I don't need to deliver the unit tests to customers (or limit my unit tests to debug builds). In addition, I can still write unit tests for all my internal classes.

Back to top














Java Pro | Visual Studio Magazine | Windows Server System Magazine
.NET Magazine | Enterprise Architect | XML & Web Services Magazine
VSLive! | Thunder Lizard Events | Discussions | Newsletters | FTP Home