Reputation: 93357
It's weird that this is the first time I've bumped into this problem, but:
How do you define a constructor in a C# interface?
Edit
Some people wanted an example (it's a free time project, so yes, it's a game)
IDrawable
+Update
+Draw
To be able to Update (check for edge of screen etc) and draw itself it will always need a GraphicsDeviceManager
. So I want to make sure the object has a reference to it. This would belong in the constructor.
Now that I wrote this down I think what I'm implementing here is IObservable
and the GraphicsDeviceManager
should take the IDrawable
...
It seems either I don't get the XNA framework, or the framework is not thought out very well.
Edit
There seems to be some confusion about my definition of constructor in the context of an interface. An interface can indeed not be instantiated so doesn't need a constructor. What I wanted to define was a signature to a constructor. Exactly like an interface can define a signature of a certain method, the interface could define the signature of a constructor.
Upvotes: 649
Views: 452166
Reputation: 9087
Almost 15 years and I'm just joining this discussion, but I've thought about this challenge for a long time.
I'm thinking that the OP's question is really something like: How can I create an Interface that forces the consumer to call a *"initialization" constructor.
*I know that "initialization" and constructor almost mean the exact same thing but I'm trying to distinguish the two as I'll demonstrate in my sample code.
Another Way Of Saying It
Maybe another way of saying it is:
Force an implementor of your Interface to call a constructor for initialization.
That's what I needed and I'll explain why with a full C# example which you can try out by running it in LINQPad.Net.
I was looking for a Interface that would help me create a framework which would allow me to WriteActivity
to any Storage
(file, DB, (post to )URL). This would allow me to trace my code while writing debug text to any end point.
Two Benefits To Solving
Trying to solve this helps me:
I've already mentioned the two things I need in my Interface and here they are in C# code:
public interface ITrackable
{
// StorageTarget is one of the following:
// 1. full-filename (including path)
// 2. DB Connection string
// 3. URI to location where data will be posted.
// STorageTarget will wrap the private var used to contain the filepath,
// connectionString, URI, etc.
String StorageTarget { get; }
bool WriteActivity(String message);
bool Configure();
}
However, now I need a way to force the implementor (implementing developer) to Configure
the StorageTarget
, because if it is not initialized then everything would fall apart. For example, in the case of the File implementation, there wouldn't be a file path to write to.
Force Configuration To Be Called
To do so, I need to create an abstract
class like the following:
public abstract class Trackable: ITrackable {
public Trackable(){
Configure();
}
public abstract bool Configure();
public abstract bool WriteActivity(String file);
public abstract string StorageTarget{get;}
}
Let's See An Implementation: FileActivityTracker
Now, there is a bit of instruction to the implementor. To create a FileActivityTracker
one we need to create use the abstract class
and the interface
that we've just created.
It will look like the following:
public class FileActivityTracker : Trackable
{
...
As soon as we create that class, we will be warned by the compiler:
FileActivityTracker
does not implement inherited abstract member Trackable.Configure()
FileActivityTracker
does not implement interface member
ITrackable.StorageTarget
FileActivityTracker
does not implement interface member ITrackable.WriteActivity(string)
This is all very good because it provides guidance to the implementing developer.
Full Implementation: Shows How Initialization Can Work
Now I'll fill all those in very quickly and we'll talk about how the code does indeed call the needed initialization constructor for the developer (which will initialize the File (string) where the FileActivityTracker
will write).
public class FileActivityTracker : Trackable
{
private String FileName;
public FileActivityTracker()
{
Console.WriteLine($"{DateTime.Now} : FileActivityTracker ctor...");
}
public override bool Configure(){
Console.WriteLine($"{DateTime.Now} : Configure() method called! ");
// Writes file to // c:\users\<user.name>
FileName = @"%userprofile%\InterfaceStudy.log";
return true;
}
public override string StorageTarget
{
get
{
return FileName;
}
}
public override bool WriteActivity(String message)
{
try
{
File.AppendAllText(StorageTarget, $"{DateTime.Now.ToLongTimeString()}:{message} {Environment.NewLine}");
return true;
}
catch (Exception ex)
{
return false;
}
}
}
Run & Output
When you run this code will output something like the following:
2024-02-11 04:07:37.844 PM : Configure() method called!
2024-02-11 04:07:37.844 PM : FileActivityTracker ctor...
And then it will write to the InterfaceStudy.log file.
The important thing here is that the Configure()
method is always called before our FileActivityTracker
attempts to write to the file, insuring that the file path is already initialized.
Success!
That's exactly what we needed: to force the implementor to call the Configure() (initialization) before our other code runs.
Bonus: How Does This Help Us With Future Extensibility?
Another implementor can come along and quickly and easily create a SqliteActivityTracker
which will write the activity to a database table.
It would look like the following. This class can be injected and used later in place of the FileActivityTracker
if desired.
public class SqliteActivityTracker: Trackable {
public SqliteCommand Command{
get{return this.command;}
set{this.command = value;}
}
private String connectionString;
private String mainPath;
private String rootPath;
private const String tempDir = "temp";
private char pathSlash = Path.DirectorySeparatorChar;
protected SqliteConnection connection;
protected SqliteCommand command;
public override string StorageTarget
{
get
{
return connectionString;
}
}
public override bool Configure(){
// read settings from configuration
rootPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}";
// insures this will r
if (!Directory.Exists(@$"{rootPath}{pathSlash}{tempDir}")){Directory.CreateDirectory(@$"{rootPath}{pathSlash}{tempDir}");}
mainPath = System.IO.Path.Combine(@$"{rootPath}{pathSlash}{tempDir}","tracker.db");
Console.WriteLine(mainPath);
connectionString = $"Data Source={mainPath}";
connection = new SqliteConnection(StorageTarget);
command = connection.CreateCommand();
return true;
}
public SqliteActivityTracker()
{
try{
// ########### FYI THE DB is created when it is OPENED ########
connection.Open();
File.AppendAllText(@$"{rootPath}{pathSlash}{tempDir}{pathSlash}InterfaceStudy.log", $"{DateTime.Now.ToLongTimeString()}: {Environment.CurrentDirectory} {Environment.NewLine}");
FileInfo fi = new FileInfo(@$"{rootPath}{pathSlash}{tempDir}{pathSlash}tracker.db");
if (fi.Length == 0){
connectionString = fi.Name;
foreach (String tableCreate in allTableCreation){
command.CommandText = tableCreate;
command.ExecuteNonQuery();
}
}
Console.WriteLine(connection.DataSource);
}
finally{
if (connection != null){
connection.Close();
}
}
}
public override bool WriteActivity(String message)
{
Command.CommandText = @"INSERT into Task (Description)values($message);select * from task where id =(SELECT last_insert_rowid())";
Command.Parameters.AddWithValue("$message",message);
try{
Console.WriteLine("Saving...");
connection.Open();
Console.WriteLine("Opened.");
// id should be last id inserted into table
var id = Convert.ToInt64(command.ExecuteScalar());
Console.WriteLine("inserted.");
return true;
}
catch(Exception ex){
Console.WriteLine($"Error: {ex.Message}");
return false;
}
finally{
if (connection != null){
connection.Close();
}
}
}
protected String [] allTableCreation = {
@"CREATE TABLE Task
( [ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[Description] NVARCHAR(1000) check(length(Description) <= 1000),
[Created] NVARCHAR(30) default (datetime('now','localtime')) check(length(Created) <= 30)
)"
};
}
Here's How Easy It Is To Call
ITrackable fat = new FileActivityTracker();
fat.WriteActivity("The app is running.");
ITrackable sat = new SqliteActivityTracker();
sat.WriteActivity("This is from the app!");
Get The Code: GitHub
Complete example ready to build and run.
You can get the code at my github: https://github.com/raddevus/InterfaceStudy
Just tested on Linux also and it runs there too.
Upvotes: 0
Reputation: 11163
.NET 7 introduced static virtual interface members. Which can be used to define factory methods that all implementations must define. And allowing generic code to call them.
public interface IFactoryType<T>
{
public static abstract T Factory(int value);
}
public class Foo : IFactoryType<Foo>
{
public static Foo Factory(int value)
=> throw new NotImplementedException();
}
public class Test
{
public void TestType<T>() where T : IFactoryType<T>
{
var foo = T.Factory(1);
}
}
Upvotes: 0
Reputation: 41
I use the following pattern to make it bulletproof.
Try it out you can't break it without making modifications to the base classes (except if you define an obsolete flag without error flag set to true, but even then you end up with a warning)
public abstract class Base<TSelf, TParameter>
where TSelf : Base<TSelf, TParameter>, new()
{
protected const string FactoryMessage = "Use YourClass.Create(...) instead";
public static TSelf Create(TParameter parameter)
{
var me = new TSelf();
me.Initialize(parameter);
return me;
}
[Obsolete(FactoryMessage, true)]
protected Base()
{
}
protected virtual void Initialize(TParameter parameter)
{
}
}
public abstract class BaseWithConfig<TSelf, TConfig>: Base<TSelf, TConfig>
where TSelf : BaseWithConfig<TSelf, TConfig>, new()
{
public TConfig Config { get; private set; }
[Obsolete(FactoryMessage, true)]
protected BaseWithConfig()
{
}
protected override void Initialize(TConfig parameter)
{
this.Config = parameter;
}
}
public class MyService : BaseWithConfig<MyService, (string UserName, string Password)>
{
[Obsolete(FactoryMessage, true)]
public MyService()
{
}
}
public class Person : Base<Person, (string FirstName, string LastName)>
{
[Obsolete(FactoryMessage,true)]
public Person()
{
}
protected override void Initialize((string FirstName, string LastName) parameter)
{
this.FirstName = parameter.FirstName;
this.LastName = parameter.LastName;
}
public string LastName { get; private set; }
public string FirstName { get; private set; }
}
[Test]
public void FactoryTest()
{
var notInitilaizedPerson = new Person(); // doesn't compile because of the obsolete attribute.
Person max = Person.Create(("Max", "Mustermann"));
Assert.AreEqual("Max",max.FirstName);
var service = MyService.Create(("MyUser", "MyPassword"));
Assert.AreEqual("MyUser", service.Config.UserName);
}
EDIT: And here is an example based on your drawing example that even enforces interface abstraction
public abstract class BaseWithAbstraction<TSelf, TInterface, TParameter>
where TSelf : BaseWithAbstraction<TSelf, TInterface, TParameter>, TInterface, new()
{
[Obsolete(FactoryMessage, true)]
protected BaseWithAbstraction()
{
}
protected const string FactoryMessage = "Use YourClass.Create(...) instead";
public static TInterface Create(TParameter parameter)
{
var me = new TSelf();
me.Initialize(parameter);
return me;
}
protected virtual void Initialize(TParameter parameter)
{
}
}
public abstract class BaseWithParameter<TSelf, TInterface, TParameter> : BaseWithAbstraction<TSelf, TInterface, TParameter>
where TSelf : BaseWithParameter<TSelf, TInterface, TParameter>, TInterface, new()
{
protected TParameter Parameter { get; private set; }
[Obsolete(FactoryMessage, true)]
protected BaseWithParameter()
{
}
protected sealed override void Initialize(TParameter parameter)
{
this.Parameter = parameter;
this.OnAfterInitialize(parameter);
}
protected virtual void OnAfterInitialize(TParameter parameter)
{
}
}
public class GraphicsDeviceManager
{
}
public interface IDrawable
{
void Update();
void Draw();
}
internal abstract class Drawable<TSelf> : BaseWithParameter<TSelf, IDrawable, GraphicsDeviceManager>, IDrawable
where TSelf : Drawable<TSelf>, IDrawable, new()
{
[Obsolete(FactoryMessage, true)]
protected Drawable()
{
}
public abstract void Update();
public abstract void Draw();
}
internal class Rectangle : Drawable<Rectangle>
{
[Obsolete(FactoryMessage, true)]
public Rectangle()
{
}
public override void Update()
{
GraphicsDeviceManager manager = this.Parameter;
// TODo manager
}
public override void Draw()
{
GraphicsDeviceManager manager = this.Parameter;
// TODo manager
}
}
internal class Circle : Drawable<Circle>
{
[Obsolete(FactoryMessage, true)]
public Circle()
{
}
public override void Update()
{
GraphicsDeviceManager manager = this.Parameter;
// TODo manager
}
public override void Draw()
{
GraphicsDeviceManager manager = this.Parameter;
// TODo manager
}
}
[Test]
public void FactoryTest()
{
// doesn't compile because interface abstraction is enforced.
Rectangle rectangle = Rectangle.Create(new GraphicsDeviceManager());
// you get only the IDrawable returned.
IDrawable service = Circle.Create(new GraphicsDeviceManager());
}
Upvotes: 0
Reputation: 495
The purpose of an interface is to enforce a certain object signature. It should explicitly not be concerned with how an object works internally. Therefore, a constructor in an interface does not really make sense from a conceptual point of view.
There are some alternatives though:
Create an abstract class that acts as a minimal default implementation. That class should have the constructors you expect implementing classes to have.
If you don't mind the overkill, use the AbstractFactory pattern and declare a method in the factory class interface that has the required signatures.
Pass the GraphicsDeviceManager
as a parameter to the Update
and Draw
methods.
Use a Compositional Object Oriented Programming framework to pass the GraphicsDeviceManager
into the part of the object that requires it. This is a pretty experimental solution in my opinion.
The situation you describe is not easy to handle in general. A similar case would be entities in a business application that require access to the database.
Upvotes: 2
Reputation: 3703
As already well noted, you can't have constructors on an Interface. But since this is such a highly ranked result in Google some 7 years later, I thought I would chip in here - specifically to show how you could use an abstract base class in tandem with your existing Interface and maybe cut down on the amount of refactoring needed in the future for similar situations. This concept has already been hinted at in some of the comments but I thought it would be worth showing how to actually do it.
So you have your main interface that looks like this so far:
public interface IDrawable
{
void Update();
void Draw();
}
Now create an abstract class with the constructor you want to enforce. Actually, since it's now available since the time you wrote your original question, we can get a little fancy here and use generics in this situation so that we can adapt this to other interfaces that might need the same functionality but have different constructor requirements:
public abstract class MustInitialize<T>
{
public MustInitialize(T parameters)
{
}
}
Now you'll need to create a new class that inherits from both the IDrawable interface and the MustInitialize abstract class:
public class Drawable : MustInitialize<GraphicsDeviceManager>, IDrawable
{
GraphicsDeviceManager _graphicsDeviceManager;
public Drawable(GraphicsDeviceManager graphicsDeviceManager)
: base (graphicsDeviceManager)
{
_graphicsDeviceManager = graphicsDeviceManager;
}
public void Update()
{
//use _graphicsDeviceManager here to do whatever
}
public void Draw()
{
//use _graphicsDeviceManager here to do whatever
}
}
Then just create an instance of Drawable and you're good to go:
IDrawable drawableService = new Drawable(myGraphicsDeviceManager);
The cool thing here is that the new Drawable class we created still behaves just like what we would expect from an IDrawable.
If you need to pass more than one parameter to the MustInitialize constructor, you can create a class that defines properties for all of the fields you'll need to pass in.
Upvotes: 207
Reputation:
While you can't define a constructor signature in an interface, I feel it's worth mentioning that this may be a spot to consider an abstract class. Abstract classes can define unimplemented (abstract) method signatures in the same way as an interface, but can also have implemented (concrete) methods and constructors.
The downside is that, because it is a type of class, it cannot be used for any of the multiple inheritance type scenarios that an interface can.
Upvotes: 0
Reputation: 2118
One way to solve this problem is to leverage generics and the new() constraint.
Instead of expressing your constructor as a method/function, you can express it as a factory class/interface. If you specify the new() generic constraint on every call site that needs to create an object of your class, you will be able to pass constructor arguments accordingly.
For your IDrawable example:
public interface IDrawable
{
void Update();
void Draw();
}
public interface IDrawableConstructor<T> where T : IDrawable
{
T Construct(GraphicsDeviceManager manager);
}
public class Triangle : IDrawable
{
public GraphicsDeviceManager Manager { get; set; }
public void Draw() { ... }
public void Update() { ... }
public Triangle(GraphicsDeviceManager manager)
{
Manager = manager;
}
}
public TriangleConstructor : IDrawableConstructor<Triangle>
{
public Triangle Construct(GraphicsDeviceManager manager)
{
return new Triangle(manager);
}
}
Now when you use it:
public void SomeMethod<TBuilder>(GraphicsDeviceManager manager)
where TBuilder: IDrawableConstructor<Triangle>, new()
{
// If we need to create a triangle
Triangle triangle = new TBuilder().Construct(manager);
// Do whatever with triangle
}
You can even concentrate all creation methods in a single class using explicit interface implementation:
public DrawableConstructor : IDrawableConstructor<Triangle>,
IDrawableConstructor<Square>,
IDrawableConstructor<Circle>
{
Triangle IDrawableConstructor<Triangle>.Construct(GraphicsDeviceManager manager)
{
return new Triangle(manager);
}
Square IDrawableConstructor<Square>.Construct(GraphicsDeviceManager manager)
{
return new Square(manager);
}
Circle IDrawableConstructor<Circle>.Construct(GraphicsDeviceManager manager)
{
return new Circle(manager);
}
}
To use it:
public void SomeMethod<TBuilder, TShape>(GraphicsDeviceManager manager)
where TBuilder: IDrawableConstructor<TShape>, new()
{
// If we need to create an arbitrary shape
TShape shape = new TBuilder().Construct(manager);
// Do whatever with the shape
}
Another way is by using lambda expressions as initializers. At some point early in the call hierarchy, you will know which objects you will need to instantiate (i.e. when you are creating or getting a reference to your GraphicsDeviceManager object). As soon as you have it, pass the lambda
() => new Triangle(manager)
to subsequent methods so they will know how to create a Triangle from then on. If you can't determine all possible methods that you will need, you can always create a dictionary of types that implement IDrawable using reflection and register the lambda expression shown above in a dictionary that you can either store in a shared location or pass along to further function calls.
Upvotes: 8
Reputation: 1503080
You can't. It's occasionally a pain, but you wouldn't be able to call it using normal techniques anyway.
In a blog post I've suggested static interfaces which would only be usable in generic type constraints - but could be really handy, IMO.
One point about if you could define a constructor within an interface, you'd have trouble deriving classes:
public class Foo : IParameterlessConstructor
{
public Foo() // As per the interface
{
}
}
public class Bar : Foo
{
// Yikes! We now don't have a parameterless constructor...
public Bar(int x)
{
}
}
Upvotes: 343
Reputation: 109255
A very late contribution demonstrating another problem with interfaced constructors. (I choose this question because it has the clearest articulation of the problem). Suppose we could have:
interface IPerson
{
IPerson(string name);
}
interface ICustomer
{
ICustomer(DateTime registrationDate);
}
class Person : IPerson, ICustomer
{
Person(string name) { }
Person(DateTime registrationDate) { }
}
Where by convention the implementation of the "interface constructor" is replaced by the type name.
Now make an instance:
ICustomer a = new Person("Ernie");
Would we say that the contract ICustomer
is obeyed?
And what about this:
interface ICustomer
{
ICustomer(string address);
}
Upvotes: 154
Reputation: 75
One way to force some sort of constructor is to declare only Getters
in interface, which could then mean that the implementing class must have a method, ideally a constructor, to have the value set (private
ly) for it.
Upvotes: 0
Reputation: 13835
You could do this with generics trick, but it still is vulnerable to what Jon Skeet wrote:
public interface IHasDefaultConstructor<T> where T : IHasDefaultConstructor<T>, new()
{
}
Class that implements this interface must have parameterless constructor:
public class A : IHasDefaultConstructor<A> //Notice A as generic parameter
{
public A(int a) { } //compile time error
}
Upvotes: 3
Reputation: 1713
One way to solve this problem i found is to seperate out the construction into a seperate factory. For example I have an abstract class called IQueueItem, and I need a way to translate that object to and from another object (CloudQueueMessage). So on the interface IQueueItem i have -
public interface IQueueItem
{
CloudQueueMessage ToMessage();
}
Now, I also need a way for my actual queue class to translate a CloudQueueMessage back to a IQueueItem - ie the need for a static construction like IQueueItem objMessage = ItemType.FromMessage. Instead I defined another interface IQueueFactory -
public interface IQueueItemFactory<T> where T : IQueueItem
{
T FromMessage(CloudQueueMessage objMessage);
}
Now I can finally write my generic queue class without the new() constraint which in my case was the main issue.
public class AzureQueue<T> where T : IQueueItem
{
private IQueueItemFactory<T> _objFactory;
public AzureQueue(IQueueItemFactory<T> objItemFactory)
{
_objFactory = objItemFactory;
}
public T GetNextItem(TimeSpan tsLease)
{
CloudQueueMessage objQueueMessage = _objQueue.GetMessage(tsLease);
T objItem = _objFactory.FromMessage(objQueueMessage);
return objItem;
}
}
now I can create an instance that satisfies the criteria for me
AzureQueue<Job> objJobQueue = new JobQueue(new JobItemFactory())
hopefully this helps someone else out someday, obviously a lot of internal code removed to try to show the problem and solution
Upvotes: 7
Reputation: 726
The generic factory approach still seems ideal. You would know that the factory requires a parameter, and it would just so happen that those parameters are passed along to the constructor of the object being instantiated.
Note, this is just syntax verified pseudo code, there may be a run-time caveat I'm missing here:
public interface IDrawableFactory
{
TDrawable GetDrawingObject<TDrawable>(GraphicsDeviceManager graphicsDeviceManager)
where TDrawable: class, IDrawable, new();
}
public class DrawableFactory : IDrawableFactory
{
public TDrawable GetDrawingObject<TDrawable>(GraphicsDeviceManager graphicsDeviceManager)
where TDrawable : class, IDrawable, new()
{
return (TDrawable) Activator
.CreateInstance(typeof(TDrawable),
graphicsDeviceManager);
}
}
public class Draw : IDrawable
{
//stub
}
public class Update : IDrawable {
private readonly GraphicsDeviceManager _graphicsDeviceManager;
public Update() { throw new NotImplementedException(); }
public Update(GraphicsDeviceManager graphicsDeviceManager)
{
_graphicsDeviceManager = graphicsDeviceManager;
}
}
public interface IDrawable
{
//stub
}
public class GraphicsDeviceManager
{
//stub
}
An example of possible usage:
public void DoSomething()
{
var myUpdateObject = GetDrawingObject<Update>(new GraphicsDeviceManager());
var myDrawObject = GetDrawingObject<Draw>(null);
}
Granted, you'd only want the create instances via the factory to guarantee you always have an appropriately initialized object. Perhaps using a dependency injection framework like AutoFac would make sense; Update() could "ask" the IoC container for a new GraphicsDeviceManager object.
Upvotes: 5
Reputation: 64236
It would be very useful if it were possible to define constructors in interfaces.
Given that an interface is a contract that must be used in the specified way. The following approach might be a viable alternative for some scenarios:
public interface IFoo {
/// <summary>
/// Initialize foo.
/// </summary>
/// <remarks>
/// Classes that implement this interface must invoke this method from
/// each of their constructors.
/// </remarks>
/// <exception cref="InvalidOperationException">
/// Thrown when instance has already been initialized.
/// </exception>
void Initialize(int a);
}
public class ConcreteFoo : IFoo {
private bool _init = false;
public int b;
// Obviously in this case a default value could be used for the
// constructor argument; using overloads for purpose of example
public ConcreteFoo() {
Initialize(42);
}
public ConcreteFoo(int a) {
Initialize(a);
}
public void Initialize(int a) {
if (_init)
throw new InvalidOperationException();
_init = true;
b = a;
}
}
Upvotes: 0
Reputation: 9943
I was looking back at this question and I thought to myself, maybe we are aproaching this problem the wrong way. Interfaces might not be the way to go when it concerns defining a constructor with certain parameters... but an (abstract) base class is.
If you create a base class with a constructor on there that accepts the parameters you need, every class that derrives from it needs to supply them.
public abstract class Foo
{
protected Foo(SomeParameter x)
{
this.X = x;
}
public SomeParameter X { get; private set }
}
public class Bar : Foo // Bar inherits from Foo
{
public Bar()
: base(new SomeParameter("etc...")) // Bar will need to supply the constructor param
{
}
}
Upvotes: 21
Reputation: 9943
It is not possible to create an interface that defines constructors, but it is possible to define an interface that forces a type to have a paramerterless constructor, though be it a very ugly syntax that uses generics... I am actually not so sure that it is really a good coding pattern.
public interface IFoo<T> where T : new()
{
void SomeMethod();
}
public class Foo : IFoo<Foo>
{
// This will not compile
public Foo(int x)
{
}
#region ITest<Test> Members
public void SomeMethod()
{
throw new NotImplementedException();
}
#endregion
}
On the other hand, if you want to test if a type has a paramerterless constructor, you can do that using reflection:
public static class TypeHelper
{
public static bool HasParameterlessConstructor(Object o)
{
return HasParameterlessConstructor(o.GetType());
}
public static bool HasParameterlessConstructor(Type t)
{
// Usage: HasParameterlessConstructor(typeof(SomeType))
return t.GetConstructor(new Type[0]) != null;
}
}
Hope this helps.
Upvotes: 20
Reputation: 336
you don't.
the constructor is part of the class that can implement an interface. The interface is just a contract of methods the class must implement.
Upvotes: 0
Reputation: 55435
You can't.
Interfaces define contracts that other objects implement and therefore have no state that needs to be initialized.
If you have some state that needs to be initialized, you should consider using an abstract base class instead.
Upvotes: 69