It is valid (ie. it compiles and runs) to put an attribute on the generic parameter for a class or a method:
public class MyClass<[My] T>
{
private void MyMethod<[My] T>()
{}
}
public class MyAttribute : Attribute
{}
I've never seen this used, and am struggling to come up with a reason as to why you would want to.
Is it just a quirk/side-effect of the language specification, or is there a valid/useful reason to put an attribute in this position?
For the same reason attributes are useful on any construct; they supply meta-data that can be used by Reflection or other post-processors to do various things. For instance, you might have an AOP system that uses an attribute on a type argument to apply certain run-time constraints that otherwise could not be expressed. I'm not sure if there are any systems that actually use these attributes to do anything, but there's no reason to disallow them as metadata.
I'm sure some AOP nut will find a valid reason to decorate generic parameters with attributes. I certainly can't think of any. Try this:
typeof(MyClass<>).GetGenericArguments().GetCustomAttributes().OfType<MyAttribute>();
If this Enumerable has any elements, then it is possible to access the attribute you placed on the class's generic parameter. If not, then you can't and thus having data you'd expect to access from any other class in your codebase is pointless. HOWEVER, they can still have code that runs when instantiated, and they're instantiated by the runtime when the generic class comes into scope, allowing you to perform aspect-oriented logic in the attribute itself. Exactly what that would be, and how it would be any different than decorating the generic class or method directly, is left as an exercise to people who worship AOP far more than I do.
Related
I'm developing a framework where a class inheriting from an abstract class of the framework needs to be able to specify the schema for the options it can accept when it is called to DoStuff().
I started out with an abstract GetOptionsSchema() method like this:
public abstract class Widget
{
public abstract OptionsSchema GetOptionsSchema();
public abstract void DoStuff(Options options);
}
Other developers would then extend on my framework by creating custom Widget types:
public abstract class FooWidget: Widget
{
public overide DoStuff(Options options)
{
//Do some FooWidget stuff
}
public overide OptionsSchema GetOptionsSchema()
{
//Return options for FooWidget
}
}
This works but requires the framework to create an instance of every Widget type to determine options schema they accept, even if it has no need to actually DoStuff() with any of these types.
Ultimately, I'd like to be able to determine the options schema for a specific Widget type directly from a System.Type. I would create a custom OptionsSchema attribute, but constructing these schemas is more complicated then would make sense to do in the constructor of an attribute. It needs to happen in a method.
I've seen other frameworks solve similar problems by creating a custom attribute that identifies a static method or property by name. For example the TestCaseSource attribute in NUnit.
Here's what this option might look like:
public abstract class Widget
{
public abstract void DoStuff(Options options);
}
[OptionsSchemaSource(nameof(GetOptionsSchema))]
public abstract class FooWidget: Widget
{
public overide DoStuff(Options options)
{
//Do some FooWidget stuff
}
public static OptionSchema GetOptionsSchema()
{
//Return options for FooWidget
}
}
I like how the OptionsSchemaSource attribute makes it possible to get the options schema directly from a System.Type, but this also seem much less discoverable to other developers creating custom Widget types.
With the abstract method another Widget developer knows they must override GetOptionSchema() because their code would not compile otherwise. With the OptionsSchemaSource attribute the best I could do would be to hope people read my documentation and have the framework throw an exception at run-time if it encounters a Widget with out an OptionsSchemaSource attribute.
Is there an alternative/better/recommended approach to this?
You pretty much already know everything of interest to judge what's the best approach.
As already mentioned, you cannot have static interfaces defined on your type, so there is no way you can ensure a new developer is enforced to add the attribute.
So, the two alternatives you identified are the only two I can think of.
Now, let's do a pros and cons and try to sharpen them.
Attribute
You can lessen the pain of ensuring devs put attributes on the classes with meaningful error messages. I would say that you should manage the discovery of the classes based exclusively on Attributes, not in inheritance.
If you manage everything with Attributes, you don't need to inherit from Widget.
This is a pro, because now everyone can inherit if it's desirable, and re-implement if it's preferred.
The con is that the implementation of discoverability will be more complex: you will need to use reflection at start up, get a MethodInfo, check that the method has the correct signature, give proper errors in case and invoke the method unboxing the result as needed.
Think about it: you would like a static method because you don't need to instantiate a single typed Widget instance, but actually instantiating a new Widget could very well be not a big deal.
Abstract class
Well, you enforce an inheritance chain over you developers, which could be ok, necessary or entirely optional (you judge), but you get a self documenting experience.
The apparent con is that at startup you need to instantiate a Widget for every derived type you discover, but that could very well be peanuts compared to assembly scanning and type checking and methodinfo discovery and method calls through reflection.
Ugly? Kind of. Inefficient? Not so much. And it's code that is invisible to your end user.
IMHO
I find quite a good tradeoff, when designing a framework, to put some "ugly" code inside the framework, if it means that every single implementation using the library is going to be even a little bit better.
All in all, if you're designing a library that you want to be flexible and discoverable, you should expect a developer to read at least a quick start guide. If they can read in 5 minutes a single bit of information (either "extend a base class" or "add a single or a couple attributes") and that single bit gives them an direction into discovering every aspect of widget registration, I would be ok: you can't really get much better than this.
My call: I would go the abstract class route with a smallish caveat. I really don't like having an enforced base class. So I would organize discovery at startup based on interface, IWidget, containing the GetOptionsSchema method and everything is needed to use the widget (which could be the DoStuff method, but could very well be something else). At startup you search for implementations of the interface which are not abstract, and you're good to go.
If, and only if, the only bit you really need in advance is a string or other similarly simple type, I would require an additional attribute.
[OptionsSchemaName("http://something")]
public class MyWidget : WidgetBase
{
public overide DoStuff(Options options)
{
//Do some FooWidget stuff
}
public static OptionSchema GetOptionsSchema()
{
//Return options for FooWidget
}
}
Then, your type discovery infrastructure can search for non-abstract IWidgets and throw a meaningful error right at startup like the type MyWidget is lacking an OptionsSchemaName attribute. Every implementation of IWidget must define one. See http://mydocs for information.
Bang! Nailed it!
It's not currently possible to enforce the attribute at compile time; that would've been ideal for your use case. It's also not possible to have an abstract static method, or have a static method specified in an interface; so there is no way to ensure the method is actually there at compile time, except by enforcing an instance method via abstract class or interface (which will require an instance of the type to access).
I'd go with the attribute idea - it's not unreasonable to expect developers to read documentation; even with overriding an abstract method, the developer would need to know how to construct an OptionSchema in the overridden method - back to documentation!
My company has a base database model class that is subclassed by particular instances of our product. The class represents primary keys in a database. The base class has a field, which we'll call AlwaysPresent, which is common to all instances of the product and is not used in querying.
abstract class BaseClass
{
private string AlwaysPresent
}
But it is a requirement that subclasses add at least one more field, as we will use reflection later to treat those other fields as database column names for a query. If there are no other fields, we can't query.
So, my question: is it possible to use C#'s reflection capabilities to force a non-abstract subclass to define new fields without specifying their names?
I am a Python programmer by trade, and I know exactly how to solve this kind of problem in Python using metaclasses. To my knowledge, C# does not have metaclasses. And I cannot raise an exception in the base class constructor, because (for various reasons) we don't use constructors for these classes (just initializers), and even if we did the base class constructor could be overridden.
Reflection cannot be used to force something. At least not at compile time. Via reflection you can read how a type is. In your case you can probably check its fields and throw an exception if required at run time.
In any case usually it is much better to use properties instead of fields. Properties are more extensible and better to hide the internal structure of a class.
A common way to enforce a specific design (properties or methods definition) of a class is to use interfaces.You can have also a class that implement more than one interface.
If properties names or fields are not know when designing the interface you cannot enforce your requirements at compile time but only at run time.
Another common c# technique is to decorate properties or fields with attributes. Maybe you can create a custom attribute and at run time check for fields with that attribute (always with reflection).
This can be done with aspects, specifically PostSharp. It allows you to execute custom code during compilation (in fact, it hooks on postcompile action) in the CompileTimeValidate:
http://www.postsharp.net/blog/post/Architectural-Validation
You can of course replace PostSharp with any custom code triggered on postcompile at build-time.
Turns out this is not a feature in C#, but you can write it like this to force people to implement it
abstract class BaseClass
{
private abstract string GetAlwaysPresent();
}
I've been looking into empty interfaces and abstract classes and from what I have read, they are generally bad practice. I intend to use them as the foundation for a small search application that I am writing. I would write the initial search provider and others would be allowed to create their own providers as well. My code's intent is enforce relationships between the classes for anyone who would like to implement them.
Can someone chime in and describe if and why this is still a bad practice and what, if any alternatives are available.
namespace Api.SearchProviders
{
public abstract class ListingSeachResult
{
public abstract string GetResultsAsJSON();
}
public abstract class SearchParameters
{
}
public interface IListingSearchProvider
{
ListingSeachResult SearchListings(SearchParameters p);
}
}
Empty classes and interfaces are generally only "usably useful" as generic constraints; the types are not usable by themselves, and generic constraints are generally the only context in which one may use them in conjunction with something else useful. For example, if IMagicThing encapsulates some values, some implementations are mutable, and some aren't, a method which wants to record the values associated with an IMagicThing might be written something like:
void RecordValues<T>(T it) where T:IImagicThing,IIsImmutable {...}
where IIsImmutable is an empty interface whose contract says that any class which implements it and reports some value for any property must forevermore report the same value for that property. A method written as indicated could know that its parameter was contractually obligated to behave as an immutable implementation of IMagicThing.
Conceptually, if various implementations of an interface will make different promises regarding their behaviors, being able to combine those promises with constraints would seem helpful. Unfortunately, there's a rather nasty limitation with this approach: it won't be possible to pass an object to the above method unless one knows a particular type which satisfies all of the constraints, and from which object derives. If there were only one constraint, one could cast the object to that type, but that won't work if there are two or more.
Because of the above difficulty when using constrained generics, it's better to express the concept of "an IMagicThing which promises to be immutable" by defining an interface IImmutableMagicThing which derives from IMagicThing but adds no new members. A method which expects an IImmutableMagicThing won't accept any IMagicThing that doesn't implement the immutable interface, even if it happens to be immutable, but if one has a reference to an IMagicThing that happens to implement IImmutableMagicThing, one can cast that reference to the latter type and pass it to a routine that requires it.
Incidentally, there's one other usage I can see for an empty class type: as an identity token. A class need not have any members to serve as a dictionary key, a monitor lock, or the target of a weak reference. Especially if one has extension methods associated with such usage, defining an empty class for such purpose may be much more convenient than using Object.
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.
It can definitely be useful to have an interface which extends another interface but adds nothing to it. For example, one could easily imagine use cases for an IImmutableEnumerable<T> which inherits from IEnumerable<T>, but promises that the sequence of items it returns will never change for any reason. A routine which needs to have a list of items that isn't going to change could have overloads for IEnumerable<T> and IImmutableEnumerable<T>. The first overload could check whether supplied object instance implements IImmutableEnumerable<T> and, if not, produce a new immutable list by copying the items in the original; the second overload could simply use the passed-in list directly, since it would be known to implement IImmutableEnumerable<T>.
It's somewhat harder to imagine use cases for an interface which doesn't have any members at all. Such an interface could be used in constraints to allow a routine to accept various types which had no other common base type, but unfortunately class hierarchies which are complex enough to make such a thing conceptually useful make it very difficult to persist objects which meet such constraints.
I'm making a game where each Actor is represented by a GameObjectController. Game Objects that can partake in combat implement ICombatant. How can I specify that arguments to a combat function must inherit from GameObjectController and implement ICombatant? Or does this indicate that my code is structured poorly?
public void ComputeAttackUpdate(ICombatant attacker, AttackType attackType, ICombatant victim)
In the above code, I want attacker and victim to inherit from GameObjectController and implement ICombatant. Is this syntactically possible?
I'd say it probably indicates you could restructure somehow, like, have a base Combatant class that attacker and victim inherit from, which inherits from GameObjectController and implements ICombatant.
however, you could do something like
ComputeAttackUpdate<T,U>(T attacker, AttackType attackType, U victim)
where T: ICombatant, GameObjectController
where U: ICombatant, GameObjectController
Although I probably wouldn't.
Presumably all ICombatants must also be GameObjectControllers? If so, you might want to make a new interface IGameObjectController and then declare:
interface IGameObjectController
{
// Interface here.
}
interface ICombatant : IGameObjectController
{
// Interface for combat stuff here.
}
class GameObjectController : IGameObjectController
{
// Implementation here.
}
class FooActor : GameObjectController, ICombatant
{
// Implementation for fighting here.
}
It is only syntactically possible if GameObjectController itself implements ICombatant; otherwise, I would say you have a design problem.
Interfaces are intended to define the operations available on some object; base classes identify what that object is. You can only pick one or the other. If accepting the ICombatant interface as an argument is not sufficient, it might indicate that ICombatant is defined too narrowly (i.e. doesn't support everything you need it to do).
I'd have to see the specifics of what you're trying to do with this object in order to go into much more depth.
What if you did this instead:
public class GameObjectControllerCombatant : GameObjectController, ICombatant
{
// ...
}
Then derive your combatant classes from this instead of directly from GameObjectController. It still feels to me like it's breaking encapsulation, and the awkwardness of the name is a strong indication that your combatant classes are violating the Single Responsibility Principle... but it would work.
Well, sort of. You can write a generic method:
public void ComputeAttackUpdate<T>(T attacker, AttackType type, T victim)
where T : GameObjectController, ICombatant
That means T has to satisfy both the constraints you need. It's pretty grim though - and if the attacker and victim could be different (somewhat unrelated) types, you'd have to make it generic in two type parameters instead.
However, I would personally try to go for a more natural solution. This isn't a situation I find myself in, certainly. If you need to regard an argument in two different ways, perhaps you actually want two different methods?
If you control all the classes in question, and if GameObjectController doesn't define any fields, the cleanest approach would be to define an IGameObjectController (whose properties and methods match those of GameObjectController) and an ICombatantGameObjectContoller (which derives from both IGameObjectController and ICombatant). Every class which is to be usable in situations that require both interfaces must be explicitly declared as implementing ICombatantGameObjectController, even though adding that declaration wouldn't require adding any extra code. If one does that, one can use parameters, fields, and variables of type ICombatantGameObjectController without difficulty.
If you can't set up your classes and interfaces as described above, the approach offered by Jon Skeet is a generally good one, but with a nasty caveat: to call a generic function like Mr. Skeet's ComputeAttackUpdate, the compiler has to be able to determine a single type which it knows is compatible with the type of the object being passed in and with all of the constraints. If there are descendants of GameObjectController which implement ICombatant but do not derive from a common base type which also implements GameObjectController, it may be difficult to store such objects in a field and later pass them to generic routines. There is a way, and if you need to I can explain it, but it's a bit tricky.