method overloading and polymorphism - c#

I'm writing a .NET web application in which administrators can customize the various data entry forms presented to their users. There are about half a dozen different field types that admins can create and customize (i.e. text, numeric, dropdown, file upload). All fields share a set of base attributes/behaviors (is the field required? Will it have a default field value?). There are also a series of field specific attributes/behaviors (i.e dropdown has a data source attribute, but text field does not). I'm leaving out many other characteristics of the problem domain for simplicity's sake.
The class hierarchy is straightforward: An abstract superclass that encapsulates common behaviors/attributes and about half a dozen concrete subclasses that deal with field specific stuff.
Each field type is rendered (i.e. mapped to) as a specific type of .NET server control, all of which derive from System.Web.UI.Control.
I created the following code to map values between the field domain objects and their corresponding UI control:
public static void Bind(Control control, IList<DocumentFieldBase> fieldBaseList)
foreach (DocumentFieldBase fieldBase in fields){
if (typeof (DocumentFieldText).IsInstanceOfType(fieldBase)){
TextBox textbox = (TextBox) control;
textbox.Text = (fieldBase as DocumentFieldText).GetValue();
}
if (typeof (DocumentFieldDropDown).IsInstanceOfType(fieldBase)){
DropDown dropDown= (DropDown) control;
dropDown.Text = (fieldBase as DocumentFieldSelectOne).GetValue().Text;
dropDown.DataSource= (fieldBase as DocumentFieldSelectOne).DataSource;
dropDown.Id= (fieldBase as DocumentFieldSelectOne).GetValue().Id;
}
//more if statements left out for brevity
}
}
I want to ditch those ungodly if statements that perform type checking. The approach I was shooting for was to create a method overload for each combination of field/control using subclass typing. For example:
public static void Bind(TextBox control, DocumentFieldText fieldText){
//some implementation code
}
public static void Bind(DropDown control, DocumentFieldDropDown fieldDropDown){
//some implementation code
}
I was hoping that I could then rely on .NET to call the appropriate overload at runtime using the specific subclass being used: For example:
foreach (DocumentFieldBase field in fields){
Control control = FindControl(field.Identifier);
Bind(control, field)
}
Unfortunately, the compiler chokes when I try this:
Argument '1': cannot convert from 'System.Web.UI.Control' to 'TextBox'.
If I have to cast the first argument to TextBox, I'm back to performing type checking myself and defeats the whole purpose of this exercise.
Is what I'm trying to achieve a) possible and b) a good idea?

Prior to C# 4, all overloading is done at compile time. You have to use double dispatch or the visitor pattern to effectively overload at execution time, and that gets messy quickly.
In C# 4, you could declare a variable as dynamic and let it all get sorted out at execution time:
foreach (DocumentFieldBase field in fields){
dynamic control = FindControl(field.Identifier);
Bind(control, field)
}
Obviously that's not much help at the moment though (unless you're using VS2010b1).
One option is to use a map from Type to Action<object> but then you get inheritance issues... (you'd potentially have to keep working up the type hierarchy from the concrete type up to object until you found an entry in the map). You'd also still need to cast to the right type within the action :(

The "dispatch" tag on this question is quite appropriate: what you want is called "multiple dispatch". C# (like most mainstream languages) only supports "single dispatch", where the method to be executed is selected solely on the (runtime) type of the object you call the method on, not on the (runtime) type of its arguments.
The visitor pattern can often be used to work around this. The idea is that you give DocumentFieldBase a method (that you override in concrete subclasses) which calls a method on Control (also overridden in concrete subclasses) that does the actual work.
Unfortunately, the source code of the Control class is probably not under your control*... so you'll have to resort to an even more hackish solution. The accepted answer to this question provides one that uses reflection.
*Extension methods are just syntactic sugar for static methods, and are thus resolved at compile time and of no use in this scenario.

Couldn't you have an abstract, non-static Bind() method in DocumentFieldBase, then do the downcasting inside each concrete class's implementation of it? Each DocumentFieldBase class knows what type of Control it's getting, doesn't it?

Related

Does C# generate separate methods when you use a Generic Parameter with constraints?

I want to implement a WPF function that can raise events on a wide variety of things - from Hyperlinks to Buttons. Both a hyperlink and a button are DependencyObjects that implement IInputElement.
I wrote this function:
private void DoStuff<T>(T element, RoutedEvent anEvent) where T : DependencyObject, IInputElement
{
element.RaiseEvent(anEvent);
}
This works great, but made me wonder if my code would generate a new method for labels, buttons, contentcontrols, hyperlinks, and anything else that I passed into it? Do you know? It seems like that would be a waste of resources in this case because my method does the same thing to all of them.
I found lots of helpful references on how to constrain generic methods, but not much on code generation. I believe C++ does generate entire new classes when using generics, but wasn't sure about C#.
The method definition is compiled in MSIL only once. You can verify the claim by dumping the IL, indeed, this is the designed behaviour because you describe what you want: a method with placeholders.
However, at runtime, things get more difficult: the JIT compiler will emit as many copies as necessary of your generic each time with different object size.
Keep in mind that these are implementation details and are subject to change across versions.
In particular, reference types share the same method as they inner runtime class is the same, while each value types get their own method.
The link posted in the comments, for example, gives you an insight of the process.

Dynamic object against Interface Method

I'm rewriting a desktop solution and I have the main root Form, that contains Properties that should be accessible by other elements of the application.
You could use an Interface method to get the property or your could get the Form as a dynamic object and query the property. Code example below.
Interface-based approach
public interface IUersInterfaceMainScreenGet
{
dynamic GetClientDetails();
}
The forms interface-implementation looks like this:
public dynamic GetClientDetails()
{
return currentClients;
}
Calling the Interface
var mainScreen = (InterfaceProject.IUersInterfaceMainScreenGet)System.Windows.Forms.Application.OpenForms["mainScreenForm"];
return mainScreen.GetLastBodyPluginFormName();
Dynamic-based appraoch
dynamic form = Application.OpenForms["MainScreenForm"];
form.currentClients
Both instance needs to get the current Active form, but Which once would be the best in practice to memory usage?
With the Interface the Property that I want to get can be private, but for Dynamic it needs to be public
Your question is quite hard to understand. However I have a guess on what you mean.
When you have your interface you can get the clients details via a method called GetClientDetails. On the form its implementation simply returns the private field (not property) currentClients.
Usually it´s a good idea to know the types you handle with, so using interfaces is a good idea as you have compile-time checks on what you can access and what not. In your case you kno that the object returned from Forms.Application.OpenForms["mainScreenForm"] has a method for accessing the client-details. When using only dynamic you have no knowledge at all on the contained object, you could do everything with it - whereas the most will fail at runtime. But why do you want to throw away knowledge that you already have?
So my basic suggestion is: allways use strongly-typed interfaces. Only in a few seldom circumstances you may actually need dynamic.
Concerning the memory-footprint there is no difference between both solutions. What counts is the memory of your actual instance, which is the same, no matter on how you access the data. So you need a field in both cases. The only difference is how you access that field, one time you this happens directly (dynamic) and on the interface you access it by calling the method.
So there is no difference on the following two statements concerning memory-footprint:
var form = (IUersInterfaceMainScreenGet)Application.OpenForms["mainScreenForm"];
return form.GetClientDetails();
And
dynamic form = Application.OpenForms["MainScreenForm"];
return form.currentClients

Is this an abuse of generics?

I sometimes find myself in a situation, where I want to express a type, which is a subtype of an inbuild class (e.g. a Wiforms control) and also implements a custom interface. I have several such classes that otherwise have no relation to each other. I use generics in these cases. Here is a simplified example:
interface IDescription
{
string GetDescription();
}
...
private string getDescription<T>(T control) where T : System.Windows.Forms.Control, IDescription
{
return control.Name + control.GetDescription();
}
However this seems like a little unconventional use of generics, because generics are usually used to write type agnostic code (like generic containers). In this code on the other hand generics are used solely because the lack of sufficient type expression.
My question is: Is this an abuse of generics? Are there any better way to write such code?
UPDATE 1
As Frank Hileman pointed out in this example adding the Name property to the interface would make this a non-issue. Let me add an other example:
private string getDescription<T>(T control) where T : System.Windows.Forms.Control, IDescription
{
return getData(control) + control.GetDescription();
}
private string getData(System.Windows.Forms.Control control)
{
...
}
UPDATE 2
Please note that adding a base class is sometimes not possible. For example:
There maybe a custom class subclassing TreeNode and an other one subclassing DataGridView.
No, it is not. The fact that generics are used to create generic containers, etc. does not mean that's the only use case of generics.
In this case, since your method does the same thing for different types that implements a common interface, it's completely fine and is not an abuse.
While it is not a better way, another way to write the getDescription method is to write a non-generic method taking either a Control or IDescription as input, and performing a dynamic cast to obtain a view on the instance as a different data type. However, now any type errors will occur at run-time instead of at compile time. If you are sure that all IDescription are also controls, it would work.
Another option is to put a Name property in IDescription, and use IDescription only.

Using implicit conversion as a substitute for multiple inheritance in .NET

I have a situation where I would like to have objects of a certain type be able to be used as two different types. If one of the "base" types was an interface this wouldn't be an issue, but in my case it is preferable that they both be concrete types.
I am considering adding copies of the methods and properties of one of the base types to the derived type, and adding an implicit conversion from the derived type to that base type. Then users will be able treat the derived type as the base type by using the duplicated methods directly, by assigning it to a variable of the base type, or by passing it to a method that takes the base type.
It seems like this solution will fit my needs well, but am I missing anything? Is there a situation where this won't work, or where it is likely to add confusion instead of simplicity when using the API?
EDIT: More details about my specific scenario:
This is for a potential future redesign of the way indicators are written in RightEdge, which is an automated trading system development environment. Price data is represented as a series of bars, which have values for the open, low, high, and close prices for a given period (1 minute, 1 day, etc). Indicators perform calculations on series of data. An example of a simple indicator is the moving average indicator, which gives the moving average of the most recent n values of its input, where n is user-specified. The moving average might be applied to the bar close, or it could be applied to the output of another indicator to smooth it out.
Each time a new bar comes in, the indicators compute the new value for their output for that bar.
Most indicators have only one output series, but sometimes it is convenient to have more than one output (see MACD), and I want to support this.
So, indicators need to derive from a "Component" class which has the methods that are called when new data comes in. However, for indicators which have only one output series (and this is most of them), it would be good for them to act as a series themselves. That way, users can use SMA.Current for the current value of an SMA, instead of having to use SMA.Output.Current. Likewise, Indicator2.Input = Indicator1; is preferable to Indicator2.Input = Indicator1.Output;. This may not seem like much of a difference, but a lot of our target customers are not professional .NET developers so I want to make this as easy as possible.
My idea is to have an implicit conversion from the indicator to its output series for indicators that have only one output series.
You don't provide too many details, so here is an attempt to answering from what you provide.
Take a look at the basic differences:
When you have a base type B and a derived type D, an assignment like this:
B my_B_object = my_D_object;
assigns a reference to the same object. On the other hand, when B and D are independent types with an implicit conversion between them, the above assignment would create a copy of my_D_object and store it (or a reference to it if B is a class) on my_B_object.
In summary, with "real" inheritance works by reference (changes to a reference affect the object shared by many references), while custom type conversions generally work by value (that depends on how you implement it, but implementing something close to "by reference" behavior for converters would be nearly insane): each reference will point to its own object.
You say you don't want to use interfaces, but why? Using the combo interface + helper class + extension methods (C# 3.0 and .Net 3.5 or newer required) can get quite close to real multiple inheritance. Look at this:
interface MyType { ... }
static class MyTypeHelper {
public static void MyMethod(this MyType value) {...}
}
Doing that for each "base" type would allow you to provide default implementations for the methods you want to.
These won't behave as virtual methods out-of-the-box; but you may use reflection to achieve that; you would need to do the following from within the implementation on the Helper class:
retrieve a System.Type with value.GetType()
find if that type has a method matching the signature
if you find a matching method, invoke it and return (so the rest of the Helper's method is not run).
Finally, if you found no specific implementation, let the rest of the method run and work as a "base class implementation".
There you go: multiple inheritance in C#, with the only caveat of requiring some ugly code in the base classes that will support this, and some overhead due to reflection; but unless your application is working under heavy pressure this should do the trick.
So, once again, why you don't want to use interfaces? If the only reason is their inability to provide method implementations, the trick above solves it. If you have any other issue with interfaces, I might try to sort them out, but I'd have to know about them first ;)
Hope this helps.
[EDIT: Addition based on the comments]
I've added a bunch of details to the original question. I don't want to use interfaces because I want to prevent users from shooting themselves in the foot by implementing them incorrectly, or accidentally calling a method (ie NewBar) which they need to override if they want to implement an indicator, but which they should never need to call directly.
I've looked at your updated question, but the comment quite summarizes it. Maybe I'm missing something, but interfaces + extensions + reflection can solve everything multiple inheritance could, and fares far better than implicit conversions at the task:
Virtual method behavior (an implementation is provided, inheritors can override): include method on the helper (wrapped in the reflection "virtualization" described above), don't declare on the interface.
Abstract method behavior (no implementation provided, inheritors must implement): declare method on the interface, don't include it on the helper.
Non-virtual method behavior (an implementation is provided, inheritors may hide but can't override): Just implement it as normal on the helper.
Bonus: weird method (an implementation is provided, but inheritors must implement anyway; they may explicitly invoke the base implementation): that's not doable with normal or multiple inheritance, but I'm including it for completeness: that's what you'd get if you provide an implementation on the helper and also declare it on the interface. I'm not sure of how would that work (on the aspect of virtual vs. non-virtual) or what use it'd have, but hey, my solution has already beaten multiple inheritance :P
Note: On the case of the non-virtual method, you'd need to have the interface type as the "declared" type to ensure that the base implementation is used. That's exactly the same as when an inheritor hides a method.
I want to prevent users from shooting themselves in the foot by implementing them incorrectly
Seems that non-virtual (implemented only on the helper) will work best here.
or accidentally calling a method (ie NewBar) which they need to override if they want to implement an indicator
That's where abstract methods (or interfaces, which are a kind of super-abstract thing) shine most. The inheritor must implement the method, or the code won't even compile. On some cases virtual methods may do (if you have a generic base implementation but more specific implementations are reasonable).
but which they should never need to call directly
If a method (or any other member) is exposed to client code but shouldn't be called from client code, there is no programmatic solution to enforce that (actually, there is, bear with me). The right place to address that is on the documentation. Because you are documenting you API, aren't you? ;) Neither conversions nor multiple inheritance could help you here. However, reflection may help:
if(System.Reflection.Assembly.GetCallingAssembly()!=System.Reflection.Assembly.GetExecutingAssembly())
throw new Exception("Don't call me. Don't call me!. DON'T CALL ME!!!");
Of course, you may shorten that if you have a using System.Reflection; statement on your file. And, BTW, feel free to change the Exception's type and message to something more descriptive ;).
I see two issues:
User-defined type conversion operators are generally not very discoverable -- they don't show up in IntelliSense.
With an implicit user-defined type conversion operator, it's often not obvious when the operator is applied.
This doesn't been you shouldn't be defining type conversion operators at all, but you have to keep this in mind when designing your solution.
An easily discoverable, easily recognizable solution would be to define explicit conversion methods:
class Person { }
abstract class Student : Person
{
public abstract decimal Wage { get; }
}
abstract class Musician : Person
{
public abstract decimal Wage { get; }
}
class StudentMusician : Person
{
public decimal MusicianWage { get { return 10; } }
public decimal StudentWage { get { return 8; } }
public Musician AsMusician() { return new MusicianFacade(this); }
public Student AsStudent() { return new StudentFacade(this); }
}
Usage:
void PayMusician(Musician musician) { GiveMoney(musician, musician.Wage); }
void PayStudent(Student student) { GiveMoney(student, student.Wage); }
StudentMusician alice;
PayStudent(alice.AsStudent());
It doesn't sound as if your method would support a cross-cast. True multiple inheritance would.
An example from C++, which has multiple inheritance:
class A {};
class B {};
class C : public A, public B {};
C o;
B* pB = &o;
A* pA = dynamic_cast<A*>(pB); // with true MI, this succeeds
Then users will be able treat the derived type as the base type by using the duplicated methods directly, by assigning it to a variable of the base type, or by passing it to a method that takes the base type.
This will behave differently, however. In the case of inheritance, you're just passing your object. However, by implementing an implicit converter, you'll always be constructing a new object when the conversion takes place. This could be very unexpected, since it will behave quite differently in the two cases.
Personally, I'd make this a method that returns the new type, since it would make the actual implementation obvious to the end user.
Maybe I'm going too far off with this, but your use case sounds suspiciously as if it could heavily benefit from building on Rx (Rx in 15 Minutes).
Rx is a framework for working with objects that produce values. It allows such objects to be composed in a very expressive way and to transform, filter and aggregate such streams of produced values.
You say you have a bar:
class Bar
{
double Open { get; }
double Low { get; }
double High { get; }
double Close { get; }
}
A series is an object that produces bars:
class Series : IObservable<Bar>
{
// ...
}
A moving average indicator is an object that produces the average of the last count bars whenever a new bar is produced:
static class IndicatorExtensions
{
public static IObservable<double> MovingAverage(
this IObservable<Bar> source,
int count)
{
// ...
}
}
The usage would be as follows:
Series series = GetSeries();
series.MovingAverage(20).Subscribe(average =>
{
txtCurrentAverage.Text = average.ToString();
});
An indicator with multiple outputs is similar to GroupBy.
This might be a stupid idea, but: if your design requires multiple inheritance, then why don't you simply use a language with MI? There are several .NET languages which support multiple inheritance. Off the top of my head: Eiffel, Python, Ioke. There's probable more.

invoking method declaration without reflection

I have a base class (order) with a set of sub classes (productorder, specialorder, partsorder etc).
Only Some of these sub classes implement a particular interface (ITrackingCustomer) which has a single method declaration (object getcustdetails()).
As part of my solution all of my orders are processed in a central place, i.e. any crud methods pass through a central layer. Within this central layer I want to do the following:
If order is of type ITrackingCustomer
Then invoke method getcustdetails()
I have this working using the following code:
if (typeof(ITrackingCustomer).IsAssignableFrom(Order.GetType()))
{
MethodInfo theMethod = Order.GetType().GetMethod("getcustdetails");
object y = theMethod.Invoke(Order, null);
}
I am happy with the first part using isassignablefrom but would like to use a less performance intensive method for the second part (i.e. the reflection using invoke).
My question is:
Is there a more efficient way of doing this as I have read that using the invoke command is costly.
ITrackingCustomer ord = Order as ITrackingCustomer;
if (ord != null)
{
object y = ord.getcustdetails();
}
You can do:
if(Order is ITrackingCustomer) {
((ITrackingCustomer)Order).getcustdetails();
}
As others have mentioned, you can use the is and as operators to determine if an object is of a certain type. However, polymorphism is usually better suited for solving this type of problem.
If it is feasible, perhaps you can place a getcustdetails() method on Order. Make it virtual if it has a suitable default implementation (i.e. return no details or null), or abstract if it makes sense that all Order types must implement it. Since you have the ITrackingCustomer interface, I suspect that an abstract method won't work well. However, for Order types that implement ITrackingCustomer, you can then implement getcustdetails() accordingly.
At this point, it sounds like you would be able to do away with ITrackingCustomer, but I can't say for certain without knowing more details about how this interface is used.
Once this is done, you won't need to perform any type checks since calling Order.getcustdetails() always dispatches to the correct concrete implementation.
If you are trying to do call by name instead of invoking a member in an interface and you want to be able to call the same method thousands of times, then other than a cast (which I assume you can't do because you don't know the type) or reflection is to JIT compile the call.
Rick Strahl has a nice blog article on the performance costs of various ways to call method and the comments lead to this article which shows how to pull a delegate out to a non-virtual method.
Finally, I wrote a blog article on how to build adapter classes on the fly. What you can do with that is make a directly callable object that meets an abstract class:
public abstract class CustomerDetailsGetter {
public abstract object getcustdetails();
}
// ...
AdapterCompiler compiler = new AdapterCompiler();
AdapterFactory<CusomterDetailsGetter> factory = compiler.DefineAdapter<CustomerDetailsGetter>(Order.GetType());
// now, my code assumes you want to construct an object from whole cloth
// but the code could be changed to invoke the default constructor and set the
// adapted object.
CustomerDetailsGetter getter = factory.Construct(null)
object info = getter.getcustdetails();
Now, I need to be clear - there are only two reasons to do this:
you want to be able to have call-by-name semantics when you know the target arguments at compile time and you don't know have the target assembly, and you want your code to be CLEAN. An example of this is code that knows it wants to create and use a particular object, but doesn't know if the assembly will be available until run time and is forbidden to have a reference.
you want to call object methods a la reflection, but want to do this fast, fast, fast and will be calling them thousands or millions of times.
If it's a "call once" thing, you're way better off writing a helper method to do what you want.

Categories

Resources