How to share a derived member variable with the base class - c#

I'm using Xamarin to make an Android and iOS app. I have my code split into 3 projects: Android, iOS and common. The code is basically designed such that common code is abstract and handles the the OS agnostic side of things and the Android/iOS code inherits from the common and handles the OS specific things. However, I'm tripping over how to handle custom member variables following this paradigm, as I need to hold onto a OS specific instance so that the class can do OS things, but I also need to reference the OS specific instance in the common code to commonly handle things.
Example: A common class is comprised of a question and a chart (think public survey where you can see how other people responded). The common version of these things are responsible for retrieving their data from the appropriate places (database, server). The OS specific version of these things are responsible for displaying the UI. I would like to pass into this class the Android version of the question and chart. Then I can call the class' "retrieveData" (common) function and the class' "displayUi" (OS specific function). I would really like to reference the same member variables during this process.
If I program it 'normally', the common class would contain the common class of question and chart and the inherited Android class would access this variables. But this doesn't work because when the Android class access them, it gets the variables as common and doesn't have the OS specific functionality. If I put the variables in the Android class, then the base class doesn't know about them and I can't do common things with them.
Up to this point, I've gotten around this by using Generics. But I've recently ran into a problem with that solution (Inheriting generic can't up cast). Another solution I've thought of is using the 'new' operator on a property in the Android class to mask the inherited member variable and use the get function to automatically down cast the variable into the Android version and the set function to store the variable on the base (base.variable = value). I'm not too keen on this idea as I have to double declare the variables and I have a slight problem with collections of variables (I can either use Array.Convert (or some similar method) if I need to pass in the array/list/dictionary/etc, or I can cast as I iterate though it to do whatever it is I have to do. Not great, but doable.
I'm curious if there's other ways to to handle this situation .
Edit
Here's some simplified code:
public interface IAnsweredCommon { ... }
public interface IAnsweredAndroid : IAnsweredCommon { ... }
public abstract class ConstructorCommon<AnsweredType> where AnsweredType : IAnsweredCommon
{
protected AnsweredType Answered;
...
}
public class ConstructorAndroid : ConstructorCommon<IAnsweredAndroid> { ... }
As you can see, this version is using the generic pattern. ConstructorCommon has a variable of type AnsweredType which is treated as IAnsweredCommon within the class allowing it to do non-OS specific things with it. ConstructorAndroid inherits from ConstructorCommon using IAnsweredAndroid. This allows me to instantiate ConstructorAndroid without having to specify a type and allows it to treat the inherited AnsweredType as a IAnsweredAndroid to do OS specific things.
As mentioned in the previous question; this generic way won't work for an unrelated reason. So, to make code work in that question, I need away to replicate what the generic is doing. The only other way I can think of, is to change the Answered variable type from AnsweredType to IAnsweredCommon and to implement a new property in ConstructorAndroid that hides the Answered variable (via the 'new' keyword) and implement the get to return a casted base variable and set to set the base variable:
public abstract class ConstructorCommon
{
protected IAnsweredCommon Answered;
...
}
public class ConstructorAndroid : ConstructorCommon
{
protected new IAnsweredAndroid Answered
{
get => (IAnsweredAndroid)base.Answered;
set => base.Answered = value;
}
...
}
I'm not super crazy about this idea for the reasons I stated above, so I'm curious if there's another way.

Related

C# generics with polymorphism

Hello denizens of stack overflow, I'm having an issue (perhaps with understanding?) regarding polymorphism and generics. I want to be able to define a "system" that contains a "component". I also want to be able to extend systems and components to be able to have greater functionality.
I currently have two base classes, Component, and I/A_ComponentSystem (For the sake of brevity, I'm not going to be showing any actual code, just definitions):
public abstract class Component { }
public interface IComponentSystem { }
public interface IComponentSystem<TComponent> : IComponentSystem
where TComponent : Component { }
// The following are what should should actually be inherited from
public abstract class AComponentSystem : IComponentSystem { }
public abstract class AComponentSystem<TComponent> : AComponentSystem
where TComponent : Component { }
Below is an example component/system created:
public abstract class ITag : Component { } // This is to allow generating the code in a different binary. Hard to explain in the question, I'll clarify if need be
public class Tag : ITag { }
public abstract class ITagSystem : AComponentSystem<ITag> { }
public class TagSystem : ITagSystem { }
Below are some excerpts of actually trying to use the code/morph between the different objects (please note that the code isn't meant to be used in this way, but I'm writing unit tests to ensure compatibility between layers)
// This is the main system that will be passed around
TagSystem tagSys = new TagSystem();
// This is OK
ITagSystem ITagSys = (ITagSystem)ITagSys;
// This is OK
AComponentSystem A_TagSys = (AComponentSystem)tagSys;
// This is OK
AComponentSystem<ITag> ATag_TagSys = (AComponentSystem<ITag>)tagSys;
// This is OK
IComponentSystem I_TagSys = (IComponentSystem)tagSys;
// This is OK
IComponentSystem<ITag> ITag_TagSys = (IComponentSystem<ITag>)tagSys;
// Even the following is OK (which is why I am confused)
IComponentSystem<Tag> new_ITag_TagSys = (IComponentSystem<Tag>)tagSys;
//***This is where it blows up*** (1)
AComponentSystem<Tag> new_ATag_TagSys = (AComponentSystem<Tag>)tagSys;
I have another interface/class, SystemManager, which is defined thusly:
public interface ISystemManager
{
TComponent AddNewComponentToEntity<TComponent, TComponentSystem>(Entity e) // Please don't ask about Entity, it shouldn't be required for this snippet and I already feel like I've posted a lot)
where TComponent : Component, new() // Required for some reason or I get an error
where TComponentSystem : IComponentSystem<TComponent>;
}
Now, the specific block of code that I have here will throw an error as well:
//*** blows up here as well ***(2)
ISystemManager sysMan = new SystemManager(); // defined elsewhere
sysMan.AddNewComponentToEntity<Tag, ITagSystem>(entity);
As far as the errors that I receive, error (1) is:
Cannot convert type 'TagSystem' to 'AComponentSystem<Tag>'
Error (2) is below:
The type 'ITagSystem' cannot be used as type parameter 'TComponentSystem' in the generic type or method 'ISystemManager.AddNewComponentToEntity<TComponent,TComponentSystem>(Entity)'. There is no implicit reference conversion from 'ITagSystem' to 'IComponentSystem<Tag>'.
Now, as far as my question goes, it is thusly:
Why can I not convert TagSystem to AComponentSystem<Tag>? This seems like a valid morph.
Why is ITagSystem not converting to IComponentSystem<Tag>? It appears that Tag should still conform to ITag, which is supported.
Is there any way I could change my hierarchy while preserving my need for that many layers of abstraction?
Thank you to anyone for reading this and assisting me.
Note: Yes, this is for an EntityFramework driven game engine. I'm building it mainly as an exercise for myself, and so I can quickly spin up 3d projects for myself. Yes, I've built a few game projects before, no I'm not interested in "finishing" a game, I'm just tinkering and having fun.
Without a simpler and yet more-complete code example, it's impossible to provide specific advice in your specific scenario. However, the basic problem is that the types are indeed not convertible, just as the compiler says.
Why can I not convert TagSystem to AComponentSystem<Tag>? This seems like a valid morph.
TagSystem doesn't inherit AComponentSystem<Tag>. It inherits AComponentSystem<ITag>. These two types are not actually the same. Just because Tag inherits/implements ITag, that does not mean that AComponentSystem<Tag> automatically inherits/implements AComponentSystem<ITag>. If it did, then that would mean that a method or property of AComponentSystem<Tag> that normally would return a value of type Tag, could wind up being used in a situation where a Tag value is expected, but some other implementation of ITag is actually returned. This is because you would be able to cast to AComponentSystem<Tag>, and then use that reference to return the non-Tag implementation of ITag, to some code that only wanted Tag.
This is bad for what I hope are obvious reasons, so the compiler doesn't allow you to do that.
Why is ITagSystem not converting to IComponentSystem<Tag>? It appears that Tag should still conform to ITag, which is supported.
Without a good Minimal, Complete, and Verifiable code example, it's difficult to answer this part of your question, as the types you've shown don't appear consistent with the code you've shown. ITagSystem is declared as inheriting AComponentSystem<ITag>, which in turn implements only IComponentSystem, not IComponentSystem<TComponent>.
So based on the code shown, there's no reason even naively to think that the conversion could work. But let's assume for a moment there's a typo in the type declarations you've shown. Then the answer is basically the same as above: implementing IComponentSystem<ITag> is not the same as implementing IComponentSystem<Tag>.
Is there any way I could change my hierarchy while preserving my need for that many layers of abstraction?
Possibly. It depends on what these types actually do. Since C# 4, we've been able to specify generic type parameters on interfaces with covariance and contravariance. With a type parameter thus restricted, and interface members to match, the interface then can support specific casting scenarios like you're trying to do.
But note that this only works when the interface members really are compatible with such conversions. The compiler still won't let you do anything unsafe.
There are a lot of questions on Stack Overflow already discussing this. Technically your question could even be considered a duplicate of those. I hope the above addresses your immediate concerns, and gives you enough information to do more research and see if generic interface variance will work in your situation. If you need more help, I recommend you post a new question and make sure to include a good MCVE that clearly illustrates your question in the simplest way possible.
TagSystem distantly inherits AComponentSystem<ITag>, but you are trying to convert it to AComponentSystem<Tag>. (Note the lack of an "I" in the generic type.) Those two generic types of AComponentSystem<> are completely different, and you cannot freely cast between the two.
Same as point 1, just because Tag is a child of ITag doesn't mean that IComponentSystem<Tag> is a child of IComponentSystem<ITag>.
The answer is almost certainly yes, though exactly how depends entirely on how you are going to use it. You might also want to ask yourself if you really need this many layers of abstraction.
To give a better example of my first point, take for example a common generic type: the List. If generics followed the same inheritance rules as normal classes, then List<Car> would be a subtype of List<Vehicle>. But the difference between the two is that the first list can only hold cars, while the second list can hold any vehicle. So if these lists were parent and child, you would be able to do the following:
List<Car> cars = new List<Car>();
List<Vehicle> vehicles = (List<Vehicle>)cars;
vehicles.Add(new Truck());
You see the problem? The general rules of inheritance just allowed us to add a non-Car object to out list of cars. Or they would, provided that is a legal cast, which it isn't. In reality, List<Car> and List<Vehicle> are not related in any way, but are actually completely separate classes with no direct relation whatsoever.

C# in Unity 3D/2D: Am I required to use Classes for every script?

A little background: I'm new to C# and Unity, but catching on very quickly. I'm also hoping this thread will not spark a debate about the merits of classes and abstract coding, as that debate is unrelated and well-worn (and unnecessarily heated); so please keep that in mind.
I'm simply wondering if every C# script in Unity is required to have a main class in any way or for any reason.
Or instead, can methods, and variables can be written outside of a class in a blank file (with namespaces) to be used in a video game?
I'm asking because, when I create a new C# script, it seems to force a class into my file and I'm afraid of breaking things.
I hope to keep code abstraction to a minimum, and the current project
I'm working on has several situations where a class is not needed, or
only one instance of the class will be used. I'd like to simply avoid
using classes in those cases.
In terms of declaring/defining variables and methods outside of any class, you can't really do that in C#. It just isn't how the language was designed (the answers to the question I linked to expand on that idea, so I won't duplicate them here).
You're not without options, though; if you have a number of variables or methods that need to be accessible from different places and don't need an object reference, you can make them static, so you won't need to instantiate the class to make use of them:
public class UtilityClass
{
public static float GravityConstant = 3.51f;
public static string GameName = "MyFirstGame";
public static float CalculateProduct(float a, float b)
{
return a * b;
}
}
Then, you can reference the class's methods/members by accessing it through its name:
float product = UtilityClass.CalculateProduct(6, 1.5f);
An example of where you might use this pattern is when defining mathematical formulae which aren't included in Unity's Mathf methods, and using them in multiple classes.
Additional note: Creating a new C# script through Unity's editor UI will default to declaring a class of the same name that inherits from Monobehaviour. You can alter it to remove the inheritance from Monobehaviour if you don't need any of the methods/attributes of the class, which avoids unnecessary overhead. One example for this would be with a static class that you never need to instantiate.
Yes, you are.
In C#, things like global variables and functions just do not exist. Everything must be contained in a class.
"But what should I do in order to declare some stuff that can be accessed everywhere, without creating an object?" you asked. There is something called the static modifier. You can access the methods or variables or fields or properties marked with this modifier without creating an object of that class.
You just add the word static in a method and it becomes a static method! How simple!
Let's see an example.
I have this non-static method:
public class MyClass {
public void DoStuff () {
}
}
I can call it like this:
var obj = new MyClass();
obj.DoStuff();
But if I modify it with static,
public class MyClass {
public static void DoStuff () {
}
}
I can call it like this:
MyClass.DoStuff();
How convenient!
Note:
Please do not misuse the static modifier! Only use it when it makes sense! When? When the method is a utility method or when the method does not belong to individual objects but the class itself.
First of All you need to check where Methods define as offical
docs stated
"Methods are declared in a class or struct by specifying the access
level such as public or private...."
So, Method should be declare in a Class or struct and A given class
should be, ideally, responsible for just one task.(see also)
Your this question "Or instead, can methods, and variables can be
written outside of a class in a blank file (with namespaces) to be
used in a video game?" answer is hidden in the below question.
Can there be stand alone functions in C# without a Class?
No. Make them static and put them in a static utility class if they indeed don't fit within any of your existing classes.
You have to make a class in order to use methods or its variable
either instance class or static class.
Am I required to use Classes for every script? Every script means you required a class. Unity Support Component Based
Architectural Design and if you require any script related
work then you definitely require a script component which means a
class require.
Finally for singleton, thanks to Unity3dWiki great detail
available. I think you will be feel comfortable to code and writing
class if you keep in mind component based architecture of Unity3d.
Singleton vs Static: I will also recommend to check this: Why do you use a Singleton class
if a Static class serves the purpose
Hope it will help.
[Note: If this helpful Any one can update this answer for future reference and use].

Hiding methods from other classes when inheriting from a class and Interface or Abstract class

To improve further implementation and to offer some guidelines and keep everything as universal as possible within the project I've created an Interface with a few methods which should be used. However only one method of this class should be visible to the user calling that class so I'd like them to be of the protected variety. E.g
public class ClassThree
{
public ClassThree()
{
var classOne = new ClassOne();
class1.MethodOne();
}
}
This despite ClassOne having 4 methods, 3 methods are used only within the one public class, hence private or protected. These 3 methods are required to make the 4th method work however (in an ideal world other developers would follow the same principle). So I don't want to see the following pop up on intellisense:
class1.MethodTwo();
class1.MethodThree();
class1.MethodFour();
I know one can implicitly call methods from an Interface e.g
IInterface.MethodTwo<Type,Type>(string name)
{
//Do stuff here
}
However I would like to prevent all the casting when calling said methods in ClassOne itself since this is just a thorn in my eye. I like my code clean and this isn't clean at all to me. I've thought of an abstract class however my class is inheriting from another class. With the interface I could just do
public ClassOne : ClassTwo, IInterface<Type1,Type2>
When I do that with an Abstract class however Visual Studio says an interface is expected. Any insights are most welcome and appreciated as I would like to up my code by making my life and that of fellow developers, who have to use my code, easier.
Thanks in advance!
Edit: The scenario is there can be several classes like ClassOne which essentially do the same however they use different types since the objects they have to return hold different values. However the buildup to these objects are more or less the same e.g:
Collect all API data
Retrieve the list to be exported to the API and call #3 or #4 depending on the type.
Export Type 1 to the API
Export Type 2 to the API
The idea is always the same but naturally different API's will require different variables. But to ensure all steps are followed as before I'd like to implement an Interface or something but step 1,2 and 3 should be private or protected and only step 2 should be available to the class that consumed it. However if I only put method 2 in the interface I can never be sure that others will implement 1,3 & 4. And that's kind of the goal here :P. This while ClassOne also inherits from another class and not just the interface.
Edit 2: I know Interfaces only provide public methods which is why I'm looking for alternatives hence this question. I know what is wrong with it I just don't really see how I can get it the way I would like it to be. Thanks for the replies so far!
Edit 3: Interface currently looks like this, I just adjusted variable names for sake of example.
public interface IExport<in T, in TU>
{
void GetRequiredApiData();
bool MethodOne(List<Type> list);
bool ExportOne(T one);
bool ExportTwo(TU two);
bool ValidateExport();
}
The other three methods should just be called inside your public method, or make your first method private/protected and call all 4 inside one public method.
The whole point of an interface is to hide exactly what is problematic for you--the other three methods that the caller doesn't need to know about.
I suspect you need to have those three methods called at separate, specific times, in a specific order. If that's the case then you have a code smell. Those methods are probably just void subroutines that have side effects and change global state. The code needs to be refactored to not be just a series of subroutines and objects need to be broken out differently.

What hack can I use to define a C# property with same name as class?

I'm using C# to make a .Net class library (a DLL) that will be distributed widely. I have an abstract class called Value, and I want it to have an abstract double property that is also called Value i.e.
public abstract class Value {
// Only accessible by subclasses within the project.
internal Value() {}
public abstract double Value {
get;
}
}
But the C# compiler won't allow this - I get the message "member names cannot be the same as their enclosing type", as discussed here.
I understand that the easiest thing to do would be to change the name of the property or the name of the class... But really I want the names to be like that, and I'm quite happy to implement an ugly hack to get it that way. So long as it works properly from external code that uses this DLL.
Unlike C#, VB.Net will allow me to define a property with the same name as the class, so I'm currently investigating merging my C# project with a VB project that defines the Value class (and its Value property) to make one DLL. This doesn't seem to be quite as straightforward as I was hoping.
Another option would be to re-write the whole project in VB... Not very appealing, but I'll consider it if necessary. I prefer C# over VB.Net but my priority is to get the built DLL the way I want it.
I'm wondering what other alternatives there might be. Any ideas for a good way to hack this?
EDIT: From the comments below it's clear that quite a number of people don't think much of the name "Value" for a class... Could anyone explain why it's so bad? I know it's not very descriptive, but I think it fits well in the context of my project. Is it because it's a keyword in C# that's used in property setters?
You cannot do that directly. You could, however, consider:
impelenting an interface with a Value member, and using explicit interface implementation (callers would have the use the interface, though)
renaming it in the class, and using an extension method to expose a Value() method, so obj.Value() works
rename it in the class, but expose it as Value in the subclasses
Ugly hack:
public abstract class ValueBase {
public abstract double Value { get; }
internal ValueBase() {}
}
public abstract class Value : ValueBase {
internal Value() {}
}
public sealed class ValueReal : Value {
public override double Value { get { return 123; } }
}
If your class is representative of a double (except for some additional metadata), you could opt for a conversion operator:
public abstract class Value
{
protected abstract double GetValue();
public static explicit operator double (Value value)
{
return value.GetValue();
}
}
Then your client code could access the metadata or cast an instance of type Value to a double. Depending on the metadata and usage, you might make the conversion implicit so you don't have to do an explicit cast, and you might define a conversion from double to Value.
There is a similar approach used by the System.Xml.Linq assembly where, for example, XElement can be cast to any primitive type as a means of accessing its "value".
As other people have said, this is not possible in C#.
Other people have criticised the name Value as a class, and while I agree it's likely too generic, I can see situations where it may make sense.
Bearing that in mind, if Value is an abstract class, perhaps ValueBase might be a decent, conformant, name? Much of the .Net framework (particularly WPF) uses XxxBase.
Another option to consider is prefixing the class name with the name of your project, as in FooValue.
Value is a terrible name for a class. It's extremely vague, so it does nothing to describe what a Value represents, and it clashes with the reserved word 'value'. You will find yourself using value = Value.Value, wondering why your code makes no sense, and eventually trying to fix a hideous bug that is a direct result of using 'value' instead of Value or value or _value or this.value. And what happens when you have to store another kind of arbitrary number? Will you call it Value2?
Name the class with a more specific and meaningful name and the problem will no longer exist. Don't fix the symptoms - fix the cause.
Even if you only rename it to "DataValue" or 'MySystemValue', you will be doing yourself a great service.
Bowing to popular opinion, I've decided to rename my Value class to DataValue. I'm pretty happy with that name, and it means I don't need any hacks to have the property called Value. So thank you very much to everyone for the feedback.
But, despite the useful answers, I still don't think the question has been answered ideally. None of the proposed solutions do exactly what was asked for, or at least not without side effects like the requirement for an otherwise-superfluous interface or public class. I should probably have been clearer in my question that I was perfectly happy to consider a hack that involved unsafe code, or modification of intermediate language or some such, as my priority was to get the public API of the DLL the way I wanted it, irrespective of whatever messy hacks might lurk hidden within it's source.
So here's the best solution that I could come up with. I haven't actually done it myself (no need now I'm using a different name for the class), but I don't have any reason to suspect that it won't work:
In the solution that contains your C# class-library project, add a new VB class-library project.
In the VB project, create the class (Value in my original example). In VB you'll have no problems adding a property with the same name as the class.
If your VB class has internal methods that need to be referenced by your C# code, reference the C# assembly using InternalsVisibleTo in your VB class.
You should now be able to reference your VB class from your C# project. But when you build the solution you'll get two separate DLLs: one for the C# code and one for the VB code. It looks like the ILMerge tool makes it very straightforward to merge the two DLLs into one (just one call from the command line).
So finally you should have a single DLL that contains the class with the property of the same name, and all the code in your C# project. Other projects that use that DLL (C#, VB, or any other .Net language) should not see your hacky effort - all they'll see is a coherent API with no superfluous public classes or interfaces.

C# has abstract classes and interfaces, should it also have "mixins"?

Every so often, I run into a case where I want a collection of classes all to possess similar logic. For example, maybe I want both a Bird and an Airplane to be able to Fly(). If you're thinking "strategy pattern", I would agree, but even with strategy, it's sometimes impossible to avoid duplicating code.
For example, let's say the following apply (and this is very similar to a real situation I recently encountered):
Both Bird and Airplane need to hold an instance of an object that implements IFlyBehavior.
Both Bird and Airplane need to ask the IFlyBehavior instance to Fly() when OnReadyToFly() is called.
Both Bird and Airplane need to ask the IFlyBehavior instance to Land() when OnReadyToLand() is called.
OnReadyToFly() and OnReadyToLand() are private.
Bird inherits Animal and Airplane inherits PeopleMover.
Now, let's say we later add Moth, HotAirBalloon, and 16 other objects, and let's say they all follow the same pattern.
We're now going to need 20 copies of the following code:
private IFlyBehavior _flyBehavior;
private void OnReadyToFly()
{
_flyBehavior.Fly();
}
private void OnReadyToLand()
{
_flyBehavior.Land();
}
Two things I don't like about this:
It's not very DRY (the same nine lines of code are repeated over and over again). If we discovered a bug or added a BankRight() to IFlyBehavior, we would need to propogate the changes to all 20 classes.
There's not any way to enforce that all 20 classes implement this repetitive internal logic consistently. We can't use an interface because interfaces only permit public members. We can't use an abstract base class because the objects already inherit base classes, and C# doesn't allow multiple inheritance (and even if the classes didn't already inherit classes, we might later wish to add a new behavior that implements, say, ICrashable, so an abstract base class is not always going to be a viable solution).
What if...?
What if C# had a new construct, say pattern or template or [fill in your idea here], that worked like an interface, but allowed you to put private or protected access modifiers on the members? You would still need to provide an implementation for each class, but if your class implemented the PFlyable pattern, you would at least have a way to enforce that every class had the necessary boilerplate code to call Fly() and Land(). And, with a modern IDE like Visual Studio, you'd be able to automatically generate the code using the "Implement Pattern" command.
Personally, I think it would make more sense to just expand the meaning of interface to cover any contract, whether internal (private/protected) or external (public), but I suggested adding a whole new construct first because people seem to be very adamant about the meaning of the word "interface", and I didn't want semantics to become the focus of people's answers.
Questions:
Regardless of what you call it, I'd like to know whether the feature I'm suggesting here makes sense. Do we need some way to handle cases where we can't abstract away as much code as we'd like, due to the need for restrictive access modifiers or for reasons outside of the programmer's control?
Update
From AakashM's comment, I believe there is already a name for the feature I'm requesting: a Mixin. So, I guess my question can be shortened to: "Should C# allow Mixins?"
The problem you describe could be solved using the Visitor pattern (everything can be solved using the Visitor pattern, so beware! )
The visitor pattern lets you move the implementation logic towards a new class. That way you do not need a base class, and a visitor works extremely well over different inheritance trees.
To sum up:
New functionality does not need to be added to all different types
The call to the visitor can be pulled up to the root of each class hierarchy
For a reference, see the Visitor pattern
Cant we use extension methods for this
public static void OnReadyToFly(this IFlyBehavior flyBehavior)
{
_flyBehavior.Fly()
}
This mimics the functionality you wanted (or Mixins)
Visual Studio already offers this in 'poor mans form' with code snippets. Also, with the refactoring tools a la ReSharper (and maybe even the native refactoring support in Visual Studio), you get a long way in ensuring consistency.
[EDIT: I didn't think of Extension methods, this approach brings you even further (you only need to keep the _flyBehaviour as a private variable). This makes the rest of my answer probably obsolete...]
However; just for the sake of the discussion: how could this be improved? Here's my suggestion.
One could imagine something like the following to be supported by a future version of the C# compiler:
// keyword 'pattern' marks the code as eligible for inclusion in other classes
pattern WithFlyBehaviour
{
private IFlyBehavior_flyBehavior;
private void OnReadyToFly()
{
_flyBehavior.Fly();
}
[patternmethod]
private void OnReadyToLand()
{
_flyBehavior.Land();
}
}
Which you could use then something like:
// probably the attribute syntax can not be reused here, but you get the point
[UsePattern(FlyBehaviour)]
class FlyingAnimal
{
public void SetReadyToFly(bool ready)
{
_readyToFly = ready;
if (ready) OnReadyToFly(); // OnReadyToFly() callable, although not explicitly present in FlyingAnimal
}
}
Would this be an improvement? Probably. Is it really worth it? Maybe...
You just described aspect oriented programming.
One popular AOP implementation for C# seems to be PostSharp (Main site seems to be down/not working for me though, this is the direct "About" page).
To follow up on the comment: I'm not sure if PostSharp supports it, but I think you are talking about this part of AOP:
Inter-type declarations provide a way
to express crosscutting concerns
affecting the structure of modules.
Also known as open classes, this
enables programmers to declare in one
place members or parents of another
class, typically in order to combine
all the code related to a concern in
one aspect.
Could you get this sort of behavior by using the new ExpandoObject in .NET 4.0?
Scala traits were developed to address this kind of scenario. There's also some research to include traits in C#.
UPDATE: I created my own experiment to have roles in C#. Take a look.
I will use extension methods to implement the behaviour as the code shows.
Let Bird and Plane objects implement a property for IFlyBehavior object for an interface IFlyer
public interface IFlyer
{
public IFlyBehavior FlyBehavior
}
public Bird : IFlyer
{
public IFlyBehaviour FlyBehavior {get;set;}
}
public Airplane : IFlyer
{
public IFlyBehaviour FlyBehavior {get;set;}
}
Create an extension class for IFlyer
public IFlyerExtensions
{
public void OnReadyToFly(this IFlyer flyer)
{
flyer.FlyBehavior.Fly();
}
public void OnReadyToLand(this IFlyer flyer)
{
flyer.FlyBehavior.Land();
}
}

Categories