You are seeing a limited-style version of this site. Please upgrade your browser to view the site as it was meant. You can try Firefox, Google Chrome, or even Safari.

Brandon Martinez

C# Interfaces: Under (No) Construction?

Posted in: Technology | , ,

Why can’t C# allow for a constructor definition in an Interface? For example, say you have this interface:

namespace ValidationServices.Customers
{
  public interface ICustomer
  {
    // Properties
    ValidationRequest Request{ get; set;}

    // Methods
    ValidationResponse ValidateOrder();
    //....
    // and so on
    //....
  }
}

And then create a class that applies that interface:

using System;

namespace ValidationServices.Customers
{
  public class Walmart : ICustomer
  {
    // Properties
    public ValidationRequest Request { get; set; }

    // Constructor
    public Walmart(ValidationRequest request)
    {
      Request = request;
    }

    #region ICustomer Members

    public ValidationResponse ValidateOrder()
    {
      // Create the Error Message
      var errorMessage = string.Empty; // Default Return

      // Check for Errors Specific to this Customer

      return (String.IsNullOrEmpty(errorMessage))
        ? new ValidationResponse {ErrorMessage = errorMessage, StatusCode = "OK"}
        : new ValidationResponse {ErrorMessage = errorMessage, StatusCode = "Fail"};
    }
    #endregion
  }

  // Extension Method for Error Messages
  public static class StringExtensions
  {
    public static void AddToErrorMessage(this string s, string newError)
    {
      s += "\n" + newError;
    }
  }
}

And another:

using System;

namespace ValidationServices.Customers
{
  public class Target : ICustomer
  {
    // Properties
    public ValidationRequest Request { get; set; }

    #region ICustomer Members

    public ValidationResponse ValidateOrder()
    {
      // Create the Error Message
      var errorMessage = string.Empty; // Default Return

      // Check for Errors Specific to this Customer

      return (String.IsNullOrEmpty(errorMessage))
        ? new ValidationResponse {ErrorMessage = errorMessage, StatusCode = "OK"}
        : new ValidationResponse {ErrorMessage = errorMessage, StatusCode = "Fail"};
    }
    #endregion
  }

  // Extension Method for Error Messages
  public static class StringExtensions
  {
    public static void AddToErrorMessage(this string s, string newError)
    {
      s += "\n" + newError;
    }
  }
}{/csharp]

If you notice, the <em>Target</em> class does <strong>not</strong> implement a constructor. As such, a value is never assigned to the <em>Request</em> property. It also means that the <em>Target</em> object would need to be initialized differently if you wanted the same results as the <em>Walmart</em> class:

[csharp]// Setup the Request Object
var request = new ValidationRequest{...setup properties here..};

// Create a new Walmart Instance
var wallyWorldChicago = new Walmart(request);

// Create a new Target Instance
var targetGreenBay = new Target();
targetGreenBay.Request = new ValidationRequest{...setup properties here...};</pre><p>If there were a way to <strong>force</strong> a constructor onto these classes, such as through the interface, it would make this process much more standard. My (ideal) implmentation would be a quick change to the original interface:</p>
<pre lang="csharp" line="1">namespace ValidationServices.Customers
{
  public interface ICustomer
  {
    // Properties
    ValidationRequest Request{ get; set;}

    // Constructors that MUST be present
    ICustomer(ValidationRequest request);

    // Methods
    ValidationResponse ValidateOrder();
    //....
    // and so on
    //....
  }
}

For now, my current workaround is to create a base class that implements the ICustomer interface, then inherit any other classes from that base class (this does have the added benefit of allowing “fallback” methods in inherited classes). Regardless, why does this implementation not exist? If it does, please let me know!

UPDATE: I should have mentioned how I was calling the CustomerBase Constructor. In any base class, you just add this for the constructor:

public Walmart(ValidationRequest request) : base(request)
{

}

Not very elegant (you have to add it to every inheriting class), but it works for now.

Share and Enjoy:
  • Facebook
  • Digg
  • Google Bookmarks
  • RSS
  • TwitThis
 

Leave a Reply