This time, I'm gonna create a math problems. I plan to have a dictionary where the key is Levels enum {Easy, Medium, Hard} and value should contain some configuration about how to create the problems.
For example:
BinaryProblemConfiguration
+ Bound1 : Bound<int>
+ Bound2 : Bound<int>
Bound has two properties: min and max.
Others types of problems don't need Bounds, but need other data.
So, I was thinking create a interface called IConfiguration.
public interface IConfiguration {}
And concrete Configurations should be:
public class BinaryProblemConfiguration : IConfiguration
{
public Bound Bound1 {get;set;}
public Bound Bound2 {get;set;}
}
public class AnotherProblemConfiguration : IConfiguration
{
// other stuff
}
The idea is to have a dictionary called ConfigurationLevels. Is this a good practice left the interface empty or means is wrong with my design?
The .NET Framework Design Guidelines calls this a "marker" interface and definitely says that it is a bad idea. They recommned using a custom Attribute instead.
Avoid using marker interfaces (interfaces with no members).
Custom attributes provide a way to mark a type. For more information about custom attributes, see Writing Custom Attributes. Custom attributes are preferred when you can defer checking for the attribute until the code is executing. If your scenario requires compile-time checking, you cannot comply with this guideline.
http://msdn.microsoft.com/en-us/library/ms229022.aspx
public sealed class ConfigurationAttribute : Attribute {
}
[ConfigurationAttribute]
public class AnotherProblemConfiguration : IConfiguration
{
// other stuff
}
Where would you use an instance of IConfiguration by itself? If there is a use case like this:
void Something(IConfiguration configuration) { ... }
Then yes, its fine. But with an empty interface, that's going to be an interesting use case. Offhand, the one that comes to mind is serializing objects, where you know that the object to be serialized via that method must be an IConfiguration, but you don't actually care about what IConfiguration looks like:
void SerializeConfiguration(IConfiguration configuration) { ... }
Now from a purely functional perspective, this would work just as well with Object, but I think it is a reasonable way of providing a compile-time mechanism for strongly suggesting that someone doesn't serialize anything but a configuration using this method.
Another common usage for these is marker interfaces, where you use reflection to find types that are 'marked' by implementing a common interface.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With