How To Get around multiple inheritance - c#

I am trying to implement the following in C# so that I can force initialization of certain event delegates and variables in the parent classes, or I would use interface's instead. Obviously the below is not syntax correct.
the concrete class is Class1 & class 2.
the idea being here MyClass Is a button and it is an Image and it is something else.
Edit: " I understand that selectable and others are not objects but states. what I really want to do is to write the code that maintains the selectable state in the appropriate method because it will be the same for all of them. i.e. On click event( click location) check if i was I clicked based on my bounding box, update state to selected. I am in XNA, which is a c# polling environment, and I'm attempting to make the GUI as event driven as possible, if that makes any sense? "
public abstract class Class1
{
private int NumberNeededForMethod;
private void methodThatOccursWhenEventHappens(int NumberNeededForMethod)
{
// stuff using NumberNeededForMethod;
}
private Class1(int NumberNeededForMethod)
{
MethodDelegate += methodThatOccursWhenEventHappens(int
NumberNeededForMethod)
;
}
}
public abstract class Class2
{
private int NumberNeededForMethod2;
private void methodThatOccursWhenEventHappens2(int NumberNeededForMethod2)
{
// stuff using NumberNeededForMethod2;
}
Class2(int NumberNeededForMethod2)
{
MethodDelegate += methodThatOccursWhenEventHappens(int NumberNeededForMethod2);
}
}
public class ClassThatIsBothClass1andClass2: Class1, Class2
{
ClassThatIsBothClass1andClass2( int NumberNeededForMethod1, int NumberNeededForMethod2) : Class1(NumberNeededForMethod1),Class2(NumberNeededForMethod2)
{
}
}

You can use composition to create a class which wraps class1 and class2 and is the thing that responds to the event raised by your button.

First, of course, C# does not support multiple inheritance, so whatever polymorphism you implement will have to be accomplished using interfaces and composition.
Referring to this comment: Draggable, Selectable and Ownable are attributes of an object.
Image and Button, on the other hand, are objects.
A Button cannot be an Ownable.
But a Button can be Ownable, Draggable or Selectable. What I wonder is whether those attributes aren't just properties on a single IAshtonControl interface?
A Button can conceivably also be an Image. That makes perfect sense.
Because C# lacks multiple inheritance, you simply cannot create an AshtonButton class that derives from both Button and Image base classes.
One thing you can do is create an AshtonButton class that implements the IAshtonControl interface, and the implementation for that interface can delegate to a private instance of a worker class that does whatever work is common to all IAshtonControl instances.
Or you could have separate IOwnable, IDraggable and ISelectable interfaces if that is what is required.
Either way, it becomes possible to truthfully make the statement that AshtonButton is an IAshtonControl, is ownable, is draggable, is selectable. Those things might have different meanings (different behavior/visual effects) for different controls, or they might not, but you would hide those implementation details behind the interface(s) so that you could programmatically treat each object the same way regardless of its implementation.
It is important to separate the object from its attributes, because that affects the way you think about the problem. Draggable is not a thing, it is a characteristic of a thing.
But if your goal is to have a Button that is also an Image, some type of composition or delegation is the way to accomplish that. If you have a IAshtonImage interface, then you would implement that on both the AshtonImage class, and on the AshtonImageButton class. Then you have an internal instance (composition) of the AshtonImage class, within the AshtonImageButton class, and delegate calls to the IAshtonImage members through to the private (composed) AshtonImage instance, and so on.

Related

Call implemented interface methods, but distinguish their calls on certain objects

I'm facing a design issue where I'm trying to call all objects that implement a certain interface IInitialize that has a method "Initialize".
"IInitialize" can implement several classes like GameManager, Player, Enemy etc.
However IInitialize can be also implemented in other classes that don't have to Initialize themselves in that exact moment when I want to let's say restart the game, so I need some sort of "categorization" of Init calls so other classes don't get called when I don't need them to be.
So here I have few options like creating another empty subclass of "IInitialize" and just make a call to "Initialize" through this type. All classes that Implement subclass will get this call. (it works, but it is a correct approach - not code smell?).
Another option is to create a generic "Initialize" interface and just pass the string or something similar to distinguish between calls.
So to recap: I implement the interface to various classes, let's say "ILife" which has a method "Die" to implement in the class. However I don't want all objects of type to die at a certain time, just the required ones.
Any other ideas or am I going in the wrong direction?
Thanks in advance!
Since this question is tagged C# I will use C# in the code examples. But the solutions apply to any object oriented language as well.
This is a question of design. You have many options to solve this. I will show three:
1. Use separate interfaces that serve a certain scenarios
interface IInitializable
{
void Initialize();
}
interface IGameStartInitializable : IInitialize
{
}
If both interfaces share absolutely the same members, this solution or especially the IGameStartInitializable inteface would have the character of a tagging interface and a proof of bad design.
I don't recommend this solution.
2. Use separate containers for the objects
public List<IInitialize> DefaultInitializables = new List<IInitialize>();
public List<IInitialize> GameStartupInitializables = new List<IInitialize>();
Now that you added each objects to the corresponding collection you can easily iterate over them. This is more elegant than the first solution.
3. Use events
Introducing a GameStarting and GameStarted events would delegate the initialization to the type itself. Let the corresponding instances of type IInitialize subscribe to this event. Their event handler will invoke IInitialize.Initialize() on themselves.
class Player : IInitialize
{
public Player(IGameEngine gameEngine)
{
gameEngine.Starting += InitializeOnGameStarting;
}
private void InitializeOnGameStarting(object sender, EventArgs e)
{
gameEngine.Starting -= InitializeOnGameStarting;
// Invoke the implemented member of IInitialize
Initialize();
}
}
This is the most elegant way. It is extensible since every implementation handles it's own initialization. No filtering or sorting (add implementations to the right collection) and iterations necessary.

C# Basics - How do interfaces work and calling implemented interface

I desperately need someone to explain me the following case and how it works "under the hood". This would help me understand the concept on a much deeper level.
Unity case:
In Unity3D engine, if we want to detect a click on a UI element, we simply implement one of their premade interfaces called "IPointerClickHandler" to our custom class.
public void OnPointerClick(PointerEventData eventData)
{
// Do whatever you want in here, when you detect click on UI element
}
The script needs to be attached to each individual element, but at the end of the day, it works like a charm.
My case:
This is fascinating for me, because I'm not sure how does Unity know that my class implemented one of its interfaces and calling the appropriate method.
I would like to do a similar trick but I can't figure out how. For example, I would like to notify all classes that implement "IScore" listener which has a method "OnScoreChanged(float newScore)";
public float Score;
public interface IScore {
void OnScoreChanged(float newScore);
}
public void SetScore(int newScore) {
Score = newScore;
//Notify all classes that implement IScore interface
// .OnScoreChanged(newScore);
}``
I would probably need a reference so my idea is to get all references to classes that implement "OnScoreChanged". Is the above example the right approach and how I can make it work? Basically, I want to implement this interface in the class where I need to get notified about new score and completely forget about how this method is called. Is something like this possible?
public class MyClassB: IScore {
public void OnScoreChanged(float newScore)
{
// This just got called after score
//changed..and without any additional implementation!
}
}
P.S I know I can use delegates with events (and then subscribe to this event from other classes), but I'm really curious how can Unity just call the interface method and keep the code much cleaner (so the user doesn't subscribe to its events, etc).
One way to implement this yourself is to derive all your classes from a single base class. This base class will invoke the VIRTUAL function OnWhatever(). [Notice: all your custom Unity component classes are derived from Monobehavior.]
Then when you create your derived classes, you can simply override the virtual OnWhatever() function, with a version specific to that component.
However, if you would like to stick with interfaces only: you can now use GetComponents < T > or GetComponentsInChildren < T > and specify an Interface for the type to find. You can go even "wider", in your interface search, by calling the GetCompoentsInChildren < T > () function on ALL the Scene's "root" Objects.
Then you can simply call/invoke the interface specified OnWhatever() function, for ALL the GetComponents < T > results.

PostSharp aspect to introduce an Interface AND LocationInterception pointcuts

I have a need to implement a complex aspect which needs to be able to introduce an interface, as well as several pointcuts. I'm not sure how to do this.
My goal is to intercept some field setters on a class, so that I can introduce some behaviour (via event handlers on the decorated fields). I want to transform some data, and then raise an event which is declared on a specific interface, so I want to introduce this interface to the class which contains these fields.
The simplest concept would be a container which captures all events on its children and transforms them into a single external event on the container class.
So, I know how to introduce method pointcuts using LocationInterceptionAspect;
public override void OnSetValue(LocationInterceptionArgs args)
{
// attach event handler to args.Value.SomeEvent,
}
And also how to introduce interfaces/methods with an InstanceLevelAspect.
But not how to combine the 2 into a single aspect.
I can't simply introduce an interface or member inside a LocationInterceptionAspect, as the scope is the location, not the containing type, and it won't compile.
I could always separate this into 2 aspects, however this means each aspect will not function independently, and I'd have to ensure both are always applied together.
It appears that I can add an OnLocationSetValueAdvice (via attributes) to an InstanceLevelAspect, and this works.
[IntroduceInterface(typeof(IMyInterface)]
public class CustomAspect : InstanceLevelAspect
{
[OnLocationSetValueAdvice]
[MulticastPointcut(Targets = MulticastTargets.Field, Attributes = MulticastAttributes.Instance)]
public void OnSetValue(LocationInterceptionArgs args)
{
...
}
}

Performing a common action on derived types

Is there a neat way to make several classes (which say derive from 1 interface), to each perform a same action? Think of http modules in ASP.NET which serve each request (Each the key word) - is there a way to perform some common action on derived types? Reflection may be one way, though I would be interested in a way at a base class level.
Thanks
Not with only an interface; you'd want an abstract class in the middle there:
abstract class Whatever : IFooable {
public virtual void Do () {
PreDo();
}
protected abstract void PreDo();
}
Then you call Do, and PreDo is automatically called first on all implementing types.
(Edit: Just to be clear, I made Do virtual so this means if you re-implement it you should call base.Do() as the first thing, just to ensure that it actually calls the parent method).
If your classes all derive from a common base class, you could put this logic in your common base class.
If I understand what you are asking correctly, then perhaps an event handler is the way to go?
If you need a bunch of objects to respond to some action, then events (also called "message passing") is the way to go.
Something like this?
class Foo
{
public event EventHandler PerformAction;
private void OnActionNeeded()
{
// A bunch of Bars need to do something important now.
if (PerformAction != null)
PerformAction.Invoke();
}
}
class Bar
{
public Bar(Foo fooToWatch)
{
fooToWatch.PerformAction += new EventHandler(Foo_PerformAction);
}
void Foo_PerformAction(object sender, EventArgs e)
{
// Do that voodoo that you do here.
}
}
May not be a complete answer but I am tempted to think in terms of AOP and attributes.
some references:
http://www.codeproject.com/KB/cs/ps-custom-attributes-1.aspx
http://www.postsharp.org/contributions/documentation/removing-duplicate-code-in-functions
The Template Method design pattern may apply to what you're asking.
http://www.dofactory.com/Patterns/PatternTemplate.aspx
The overall point of designing an interface is to provide a protocol between two components and hide the implementation part.
The interfaces serve as a communication medium.
And what you are asking seem to be specific to implementaion.
Which can be cleanly handled using utility classes(singleton with the method)
I do not suggest to have abstract class in ur current scenario.

UserControl as an interface, but visible in the Designer

So we have a C# WinForms project with a Form that contains a bazillion UserControls. Each UserControl naturally exposes all the UserControl methods, properties, etc. in addition to its own specific members.
I've been thinking that one way to reduce the complexity of dealing with these UserControls is to access them through an interface. So instead of drag-and-drop to put the UserControl on the form, something like this in the constructor:
public class MyGiantForm
{
ICustomerName cName;
public MyForm()
{
InitializeComponent();
var uc = new SomeCustomerNameUserControl();
this.Controls.Add(uc);
cName = uc;
}
}
SomeCustomerNameUserControl implements ICustomerName, naturally, and ICustomerName contains the specific properties I really care about (say, FirstName and LastName). In this way I can refer to the UserControl through the cName member and, instead of being bowled over by all the UserControl members, I get only those in ICustomerName.
All well and good, but the problem is that if I do it this way, I can't see SomeCustomerNameUserControl in the Designer. Does anybody know I way I can do this but still see the UserControl on the form's design surface?
EDIT: One way to do this, which isn't overly complicated, is to put the controls on a base form. By default (in C#) the control members are private. Then I create a property for each control exposing it through the interface.
However, I'd be interested in some other way to do this, even if it's more complex. There seems to be some way to do it with IDesignerHost, but I can't find any applicable examples.
If SomeCustomerNameUserControl is defined like this:
class SomeCustomerNameUserControl : UserControl, ICustomerName
{
}
You can still drop this control in the designer (which creates someCustomerNameUserControl1) and do this whenever you need to:
ICustomerName cName = someCustomerNameUserControl1;
Maybe I'm missing something, but I think it's that simple.
There's a way to accomplish what you want -- hiding the members you don't want to see -- but make it apply automatically, without requiring others' cooperation in terms of them using a custom interface. You can do it by reintroducing all the members you don't want to see, and tagging them with attributes.
This is what Windows Forms does when, for example, a base-class property doesn't mean anything for a particular descendant. For example, Control has a Text property, but a Text property is meaningless on, say, a TabControl. So TabControl overrides the Text property, and adds attributes to its override saying "By the way, don't show my Text property in the Property Grid or in Intellisense." The property still exists, but since you never see it, it doesn't get in your way.
If you add an [EditorBrowsable(EditorBrowsableState.Never)] attribute to a member (property or method), then Intellisense will no longer show that member in its code-completion lists. If I'm understanding your question correctly, this is the big thing you're trying to achieve: make it hard for application code to use the member by accident.
For properties, you probably also want to add [Browsable(false)] to hide the property from the Property Grid, and [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] to prevent the designer from writing the property's value to the .designer.cs file.
These will make it very difficult to accidentally use the method/property. They're still not a guarantee, though. If you do need a guarantee, then throw in an [Obsolete] attribute too, and build with "Treat warnings as errors" -- then you're taken care of.
If the base member is virtual, you probably want to override it, and have your override simply call base. Don't throw an exception, since the overridden member will probably be called by the base class during the normal course of events. On the other hand, if the base member isn't virtual, then you want to use "new" instead of "override", and you can decide whether your implementation should call base, or just throw an exception -- nobody should be using your reintroduced member anyway, so it shouldn't matter.
public class Widget : UserControl
{
// The Text property is virtual in the base Control class.
// Override and call base.
[EditorBrowsable(EditorBrowsableState.Never)]
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Obsolete("The Text property does not apply to the Widget class.")]
public override string Text
{
get { return base.Text; }
set { base.Text = value; }
}
// The CanFocus property is non-virtual in the base Control class.
// Reintroduce with new, and throw if anyone dares to call it.
[EditorBrowsable(EditorBrowsableState.Never)]
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Obsolete("The CanFocus property does not apply to the Widget class.")]
public new bool CanFocus
{
get { throw new NotSupportedException(); }
}
// The Hide method is non-virtual in the base Control class.
// Note that Browsable and DesignerSerializationVisibility are
// not needed for methods, only properties.
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("The Hide method does not apply to the Widget class.")]
public new void Hide()
{
throw new NotSupportedException();
}
}
Yes, this is a fair bit of work, but you only have to do it once... per member, per class... umm, yeah. But if those base-class members really don't apply to your class, and having them there will cause confusion, then it may be worth going to the effort.
'I want ICustomerName to be the only option for accessing the UserControl's variable. The idea is that a developer doesn't have to "just remember" to cast it.'
The problem you are having is that you have two completely divergent uses for your form and the controls it hosts. There is no trick built into Visual Studio or winforms which solves this neatly for you. It may be possible, but there is a much cleaner and object oriented way to separate the two methods of interacting with the controls.
If you want to hide the fact that these objects inherit from UserControl, and just want to treat them as IDoSomeThingYouShouldDealWith, you need to separate the logic that deals with the presentation concerns (designer + UI logic) from your business logic.
Your form class, should rightly deal with the controls as UserControls, docking, anchoring etc etc, nothing special here. You should put all the logic that needs to deal with ICustomerName.FirstName = etc into a completely separate class. This class doesn't care or know about fonts and layout, it just knows that there is another instance that can present a customer name; or a DateTime as a 'date of birth choosing' control properly etc.
This is a really lame example, but I have to go right now. You should be able to get the idea covered here in more detail:
public interface ICustomerName
{
void ShowName(string theName);
}
public partial class Form1 : Form, ICustomerName
{
public Form1()
{
InitializeComponent();
}
#region ICustomerName Members
public void ShowName(string theName)
{
//Gets all controls that show customer names and sets the Text propert
//totheName
}
#endregion
}
//developers program logic into this class
public class Form1Controller
{
public Form1Controller(ICustomerName theForm) //only sees ICustomerName methods
{
//Look, i can't even see the Form object from here
theForm.ShowName("Amazing Name");
}
}
After you add the UserControl using the designer, you can set GenerateMember to false in the Properties window to suppress generation of a member.
You could then use some other technique in the constructor to assign your cName reference, e.g.:
foreach(Control control in this.Controls)
{
cName = control as ICustomerName;
if (cName != null) break;
}
cName would then be the only reference to the UserControl.
You could write an extension method that would allow you to return any controls on the form that implement an interface.
public static class FormExtensions
{
public static IDictionary<string, T> GetControlsOf<T>(this Form form)
where T: class
{
var result = new Dictionary<string, T>();
foreach (var control in form.Controls)
{
if ((control as T) != null)
result.Add((control as T).Tag, control as T);
}
return result;
}
}
Then in your form you could call it whereever you want by:
this.GetControlsOf<ICustomerName>()["NameOfControlHere"];
In the event that it returns more than one user control you would need to handle that some how, perhaps by adding Tag property to the interface to uniquely keep track of each user control or something, like so
public partial class UserControl1 : UserControl, ICustomerName
{
public string Tag { get { return this.Name; } }
}
You can then drag and drop the user controls onto your form from the designer. Tag will always return the name of your control, which will allow you to directly access the control through the IDictionary's interface. You're developers could put whatever unique identifier they want in the name of the control, and it would carry through to the interface.
Also, it should be noted that this approach will ALSO allow you to use this on ALL forms in your solution.
The only other thing you would need to do is set your GenerateMember to false.
you could as well do as Bob said but assign all your member variables in the constructor, then you have it in one place.
It almost seems like you want to implement a mediator pattern. Instead of having to deal with each of the bazillion UserControls directly, you'd interact with them through the mediator. Each mediator would define the slim interface you want to see from each control. This would reduce the overall complexity by making your design more explicit and concise. For example, you wouldn't need the 20 properties and 50 methods available on one of your controls. Instead you'd deal with the mediator for that control which defines the 2 properties and 5 methods you really care about. Everything would still show up in the designer, but other parts of your app would not be interacting with those controls -- they'd interact with the mediators.
One of the big advantages to this approach is it greatly simplifies your maintenance. If you decide the MyCrappyUserControl needs to be rewritten because the implementation is bad, you just need to update the mediator class for that control. All the other classes that interact with the control do so through the mediator and would be unchanged.
Ultimately it comes down to discipline: you and your team need to be disciplined enough to use the mediators/interfaces/whatever instead of the directly hitting the controls. Institute an over the shoulder code review by a leader programmer if your team is on the low end of the discipline scale.
Assume that MyUserControl is defined like this:
class MyUserControl : UserControl, IMyInterface
{
// ...
}
Then in your form, you should have something like this:
public class MyForm : Form
{
IMyInterface cName;
public MyForm()
{
InitializeComponent();
cName = new MyUserControl();
Controls.Add((UserControl)cName);
}
}
This way, cName is the only way to access this instance of our usercontrol.

Categories

Resources