C# Interfaces: Under (No) Construction?
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.
Leave a Reply