Force a Subclass to Define Extra Fields in C# - c#

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();
}

Related

Statically defining options for a type of a derived class

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!

Declare an interface as being implemented by a class

I created a class called MostRecentStack<T> which is a stack that only keeps a certain number of items, dropping the ones at the bottom to make room for new ones. I'd like to have a variable that can store a reference to either a regular ("infinite") stack, or one of my custom type, depending on the circumstances, but C# defines no generic "stack" interface. Normally this wouldn't be a problem, but I'd like System.Collections.Generic.Stack<T> to implement the interface as well.
As long as a class provides the required members, is there any way to, in the interface definition, tell the compiler to consider a class as implementing the interface? I'd like to be able to do this without having to use as or other methods of typecasting.
The exact thing you're asking for isn't possible. However, something like should be very similar to what you want:
public class CompatibleStack<T> : System.Collections.Generic.Stack<T>, IYourStackInterface<T>
{
}
The CompatibleStack is functionally equivalent to System.Collections.Generic.Stack, except it now implements IYourStackInterface.
As long as System.Collections.Generic.Stack has all the right members to implement IYourStackInterface, this should compile fine. And you can pass a CompatibleStack around as an IYourStackInterface without any problems.
No, it is not possible to add new interface to existing class that you don't own. Options:
if you get instance of the class via some dependency injection controller you may be able to wrap class with proxy that will implement interface by calling matching methods.
you can simply derive from existing class and add interface (if it is not sealed) and start using your class.
in your particular case as Baldrick pointed out you can do reverse - derive from existing class and implement interface.
you can try to use dynamic to get some duck typing (as both classes will have matching methods) for some performance, readability and strong type cost.
Side note: in general C# does not support duck typing, but there is one case (foreach) where implementing interface is not strictly required - just having correct methods on collection is enough to support foreach.

What use have attributes on generic parameters?

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.

Force calling the derived class implementation within a generic function in C#?

Ok so I'm currently working with a set of classes that I don't have control over in some pretty generic functions using these objects. Instead of writing literally tens of functions that essentially do the same thing for each class I decided to use a generic function instead.
Now the classes I'm dealing with are a little weird in that the derived classes share many of the same properties but the base class that they are derived from doesn't. One such property example is .Parent which exists on a huge number of derived classes but not on the base class and it is this property that I need to use.
For ease of understanding I've created a small example as follows:
class StandardBaseClass {} // These are simulating the SMO objects
class StandardDerivedClass : StandardBaseClass {
public object Parent { get; set; }
}
static class Extensions
{
public static object GetParent(this StandardDerivedClass sdc) {
return sdc.Parent;
}
public static object GetParent(this StandardBaseClass sbc)
{
throw new NotImplementedException("StandardBaseClass does not contain a property Parent");
}
// This is the Generic function I'm trying to write and need the Parent property.
public static void DoSomething<T>(T foo) where T : StandardBaseClass
{
object Parent = ((T)foo).GetParent();
}
}
In the above example calling DoSomething() will throw the NotImplemented Exception in the base class's implementation of GetParent(), even though I'm forcing the cast to T which is a StandardDerivedClass.
This is contrary to other casting behaviour where by downcasting will force the use of the base class's implementation.
I see this behaviour as a bug. Has anyone else out there encountered this?
I see this behaviour as a bug.
This behavior is correct. Since your method DoSomething is constraining T to StandardBaseClass, you only have access to the specific methods of StandardBaseClass, not any methods or properties of a derived class. Since StandardBaseClass does not have a Parent property, this is invalid, and should be invalid, by design.
There are two potential options here - You can use reflection to pull out the Parent property, or use C# 4's dynamic type, and treat this as a dynamic object. Both bypass the standard type checking in the compiler, however, so will require you to do extra type checking at runtime to verify that the Parent property exists.
Create an interface that contains the Parent property. Have each class that has a Parent property implement that interace. You will then be able to create a generic method that accepts a parameter of type IHaveParent, and it will do the right thing.
For anyone that is interested an succinct answer to this situation is answered by Stephen Cleary on msdn here:
http://social.msdn.microsoft.com/Forums/en-AU/csharpgeneral/thread/95833bb3-fbe1-4ec9-8b04-3e05165e20f8?prof=required
To me this is a divergence in the class hierarchy. By this this I mean that either the base class has parent, or the derived classes with Parent are derived from an abstract child of the base.
Lol as John says, an interface as opposed to an abstract class is sufficient too.
You idea won't work because the compiler can never guarantee that the base class actually would have such a property. And it won't just select the "right" one based on if it has it or not.
The only way you can do this is using reflection and then test at runtime if the requested property exists on the inspected class. You have to judge yourself if that is a viable way to do for your project (reflection is slow and requires maximum rights).
This is correct, as the compiler only knows that it can bind to your type as a StandardBaseClass. The binding is not done at runtime (where it could potentially decide to use the StandardDerivedClass overload.
If you know that it's a StandardDerivedClass, then why not just cast it as such?
object Parent = ((StandardDerivedClass)foo).Parent;
It's a bit ugly, but you can accomplish this using a Registration system, where you register delegates for different possible derived classes that expose the 'shared' property/method and then use something like a Dictionary<Type,Func<SomeT>> to store the delegates. If you know all of the derived types ahead of time and don't have to load plug-ins or the like, you can also use the classic ugly if/else-if structure. Either way you're basically creating your own substitute for what should have been supported by the virtual method table.

Encapsulation VS Inheritance - How to use a protected function?

In OOP languages like C# or VB.NET, if I make the properties or methods in a super class protected I can't access them in my Form - they can only be accessed in my class that inherits from that super class.
To access those properties or methods I need to make them public, which defeats encapsulation, or re-write them into my class, which defeats inheritance.
What is the right way to do this?
If you have code which needs to ask an Class to perform a specific operation but the class does not present your code with a means to do that then the Class doesn't fulfill you codes requirements.
Its bit like saying I've got a Car (Automobile) that has a protected steering wheel so I can't access it. The car is no use to me.
Either make those members Public (or at least internal) and use them or ditch the class and use one that gives your consuming code the features it needs.
Perhaps what you are really looking for is an interface. The interface contains the members your code needs and you implement that interface on your class. The advantage here is that your class can determine that the members are being accessed via this Interface rather than an inheriting subclass.
"need to make them public which defeats encapsulation"
Don't conflate good design with the icky visibility rules. The visibility rules are confusing. There are really two orthogonal kinds of visibility -- subclass and client. It's not perfectly clear why we'd ever conceal anything from our subclasses. But we can, with private.
Here's what's important. Encapsulation does not mean hiding. Protected and private are not an essential part of good encapsulation. You can do good design with everything being public (that's the way Python works, for example).
The protected/private stuff is -- mostly -- about intellectual property management: are you willing to commit (in a legally binding, "see-you-in-court-if-it-doesn't-work" way) to an interface? If your software development involves lawyers, then you care about adding protect and private to the things you're not committed to.
If you don't have to cope with lawyers, consider doing encapsulation right but leave everything public.
Sorry, it's not clear what you mean by "in my Form" - what is the relationship between your Form and your two classes? If your classes are controls in the same project, and you want to access properties from the form, you should use the 'internal' keyword.
There are at least three ways you can limit who can use some particular instance method of particular class instances:
Define the method as `protected`, `internal`, or `private`. In the first case, an instance method will only be usable from within derived-class methods of the same instance; in the second case, all classes within the assembly will have access to those methods, but classes outside won't; in the third case, no outside classes, even derived ones in the same assembly, will have access, unless their code is nested within the declaring class.
Define the method as `public`, but have the classes that create instances keep them private and never expose them to the outside world. Anyone wanting to invoke an instance method on an object has to have an instance to invoke it on. If a class holds instances but never exposes direct references to them, the only instance methods that can ever be used on those instances will be those which the holding classes uses itself.
Define the method as `public`, but have a constructor which accepts a location into which one or more delegates to private methods may be stored. Code with access to those delegates will be able to call the methods referred to thereby, but other code will not (except by using Reflection in ways which I think are only usable in full-trust scenarios).
If Reflection in non-full-trust scenarios would allow unbound delegates to be bound to arbitrary object instances, one could use nested classes to reinforce #3 so that one would have to access private fields to gain illegitimate access to the private functions; that would definitely be forbidden outside full-trust scenarios.

Categories

Resources