OOGenerics Design Considerations - c#

Here is the situation for which I am trying to find a suitable design.
I need to store profiles of numbers. A profile is just a series of numbers. They can be of either int, float or decimal type. Each profile has a ProfileDescription field based on an ennumeration.
Each Profile has a collection of ProfileVersion Objects. Each ProfileVersion object has a collection of ProfileValue objects. These ProfileValue objects are where the actual numerical values of the required type are stored.
My initial design idea was to make Profile, ProfileVersion and ProfileValue generic. I hit a problem when I want to have a List of Profiles of different types, which I cannot have. I could use an ArrayList instead, but then i would have to cast out the data within it.
I though it might be possible to make just ProfileVersion and ProfileValue generic, and then have the Profile Object assign a type to the ProfileVersion depending on the value of the ProfileDescription field, but I cannot find a way to do this.
Another thought was I should use a ProfileBase class and then subclass it with either a GenericProfileClass or IntProfile, FloatProfile and DecimalProfile, but this wouldn't really give me any advantage over having each class being generic, as I would have to cast out the subclass each time anyway.
I would appreciate your thoughts on the best design approach for this situation.
Thanks

Grzenio's idea is correct. Each of your profile classes could be made to be implementations of an IProfile object, and then your container could be:
class ProfileList : IList<T> where T: IProfile
Thus the only constraint you'll have is the interface, not the specific type or a casted base class.
As for:
Another thought was I should use a
ProfileBase class and then subclass it
with either a GenericProfileClass or
IntProfile, FloatProfile and
DecimalProfile, but this wouldn't
really give me any advantage over
having each class being generic, as I
would have to cast out the subclass
each time anyway.
The benefits would really depend on the level of abstractions that you make for your classes. If designed properly you can ideally have operation/business logic/or manager classes that can accept any of those base types (again via generics) without having to know the specific cast.

I am not sure if I understand your problem correctly (pasting the code that doesn't work would help), but I think that you could try to create interfaces IProfile, IProfileVersion, etc. and make the generic class inherit the interface Profile<T>:IProfile.
What you are trying to do in not easy anyway, because there is no base numeric type in C# sadly.

Related

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.

Empty interfaces and abstract class enforce structure

I've been looking into empty interfaces and abstract classes and from what I have read, they are generally bad practice. I intend to use them as the foundation for a small search application that I am writing. I would write the initial search provider and others would be allowed to create their own providers as well. My code's intent is enforce relationships between the classes for anyone who would like to implement them.
Can someone chime in and describe if and why this is still a bad practice and what, if any alternatives are available.
namespace Api.SearchProviders
{
public abstract class ListingSeachResult
{
public abstract string GetResultsAsJSON();
}
public abstract class SearchParameters
{
}
public interface IListingSearchProvider
{
ListingSeachResult SearchListings(SearchParameters p);
}
}
Empty classes and interfaces are generally only "usably useful" as generic constraints; the types are not usable by themselves, and generic constraints are generally the only context in which one may use them in conjunction with something else useful. For example, if IMagicThing encapsulates some values, some implementations are mutable, and some aren't, a method which wants to record the values associated with an IMagicThing might be written something like:
void RecordValues<T>(T it) where T:IImagicThing,IIsImmutable {...}
where IIsImmutable is an empty interface whose contract says that any class which implements it and reports some value for any property must forevermore report the same value for that property. A method written as indicated could know that its parameter was contractually obligated to behave as an immutable implementation of IMagicThing.
Conceptually, if various implementations of an interface will make different promises regarding their behaviors, being able to combine those promises with constraints would seem helpful. Unfortunately, there's a rather nasty limitation with this approach: it won't be possible to pass an object to the above method unless one knows a particular type which satisfies all of the constraints, and from which object derives. If there were only one constraint, one could cast the object to that type, but that won't work if there are two or more.
Because of the above difficulty when using constrained generics, it's better to express the concept of "an IMagicThing which promises to be immutable" by defining an interface IImmutableMagicThing which derives from IMagicThing but adds no new members. A method which expects an IImmutableMagicThing won't accept any IMagicThing that doesn't implement the immutable interface, even if it happens to be immutable, but if one has a reference to an IMagicThing that happens to implement IImmutableMagicThing, one can cast that reference to the latter type and pass it to a routine that requires it.
Incidentally, there's one other usage I can see for an empty class type: as an identity token. A class need not have any members to serve as a dictionary key, a monitor lock, or the target of a weak reference. Especially if one has extension methods associated with such usage, defining an empty class for such purpose may be much more convenient than using Object.

How to configure the factory to generate the object?

Maybe the title is not so clear. Let me clarify what I'm trying to accomplish.
I have to base classes:
BaseProperties
BaseProblem
BaseProperties contains data about the generation of math problems. For example, in the image above, BasicAdditionProperties contains Addend1 and Addend2, this two objects know about the range of the generated value to represent a BasicAdditionProblem.
So, this is just an idea.. I guess I supposed to pass the abstract class to a factory, and this one should generate the problem (in this case BasicAdditionProblem).
I have read, it's recomended pass these values as the base class. And my main doubt is, when I pass the object BaseProperties to the factory, all the time do I have to cast the object?
Or what ideas can I implement to model this scenario? Or do I have to have a static Factory where maintain and be used as mapping to the concrete factories?
Thanks in advance.
Define an abstract CreateProblem() in the BaseProperties class. This method can be used generically to allow each concrete Properties subclass to provide its own Factory method.
This is similar to using an instance of WebRequest subclass and calling GetResponse() on it and it then returns the coresponding subclass of WebResponse.
This distributed abstract factory approach allows you to add property/problem pairs easily to the system because the code to map the two is solely contained in those two classes.
You could also use a full Abstract Factory implementation where you have PropertyProblemFactory that defines a CreateProperties() and a CreateProblem(). So in your example you would have AdditionFactory that knows how to create the matching set. But this forces you to define an additional class for each Property/Problem pair. It also works best when you have a class that uses the current/selected PropertyProblemFactory, creates a Properties with it, and then immediately uses that same PropertyProblemFactory factory to create the matching Problem. Once you let go of the reference to the factory and solely have just a reference to the Properties, it is harder to re-locate the right factory to create the Problem. (This can be addressed with yet another class to map object types to factories, but the complexity rises. So the first appoach I suggested is better in this kind of situation).
There are multiple solutions for this. It just depends on how you want to program it.
abstract methods in the abstract class must be handled in all classes that inherit from the abstract class. This way you can easily call abstract methods in the factory without casting.
However when you need to use lots of data from just one specific class then it would not be wise to make abstract methods for it and you should just simply cast the object.
So it all depends on how much classes inherit from BaseProperties and how much data in those classes are the same.

Interface vs internal variable vs inheritance dictionary

I have read
When should I choose inheritance over an interface when designing C# class libraries?
I believe I understand is-a vs must-do relationship. Having said all that here is my dilemma.
I want to implement a Collection of key value pairs most likely object. I need to add to the add and remove events only to do validation, check for duplication and some tracking stuff.
If I implement IDictionary it seems that it is a bit of an over kill to implement all the Idictionary<>, ICollection<>, IEnumerable<>, and IEnumerable. Yes most of them are one liners.
It is not recommended to inherit from Dictionary as it was never meant to be extended, shadowing the Add and remove.
Finally I can just implement a private variable and then expose the methods I want or need for the project
Any suggestions on the direction to go?
You should use composition and encapsulate a dictionary inside your class (the private variable option). This way, you only expose to the outside world the operations that make sense for your object and the fact that you use a dictionary is a mere implementation detail.
You should only implement IDictionary<,> or inherit from Dictionary<,> if your class is a generic dictionary with some special characterists.
The simplest approach would be to implement the IDictionary as an instance variable and wrap the Add and Remove methods in Add and Remove methods in your class that perform validation before adding or removing the object to or from the dictionary.
Inheritance is for when you need to inherit implementation. Otherwise, if you want to inherit interface, bit not implementation, uses interfaces.
I would suggest perhaps designing some of your own dictionary-ish interfaces which include the functionality you're interested in. Among other things, I would suggest having some interfaces which exist purely for reading the interface, and some which allow read-write access. Among other things, if you have a read-only interface, methods which don't care whether a particular dictionary is mutable or immutable will be able to use an IReadableDict (implemented by both mutable and immutable dictionaries) while routines that require either that a dictionary be mutable or that it be immutable will be able to specify that. Further, segregating out some other interfaces will allow maximum possibilities for covariance and contravariance. For example, code which is expecting an IReadableDict<String, Animal> could be perfectly happy with a Dict<String, Cat> even though code which was expecting an IReadWriteDict<String, Animal> would not be able to accept an Dict<String, Cat>. Likewise, code which only needs to know the count of a dictionary could accept a non-generic ICountable which exposes a Count method, and code which only needs to know whether a certain key exists could accept a non-generic IQueryExistence (note that one can perfectly legitimately check whether a Dict<Cat, PurrVolume> contains a particular instance of Dog; the answer will be 'no', but the question is valid).

C#: Specify that a function arg must inherit from one class, and implement an interface?

I'm making a game where each Actor is represented by a GameObjectController. Game Objects that can partake in combat implement ICombatant. How can I specify that arguments to a combat function must inherit from GameObjectController and implement ICombatant? Or does this indicate that my code is structured poorly?
public void ComputeAttackUpdate(ICombatant attacker, AttackType attackType, ICombatant victim)
In the above code, I want attacker and victim to inherit from GameObjectController and implement ICombatant. Is this syntactically possible?
I'd say it probably indicates you could restructure somehow, like, have a base Combatant class that attacker and victim inherit from, which inherits from GameObjectController and implements ICombatant.
however, you could do something like
ComputeAttackUpdate<T,U>(T attacker, AttackType attackType, U victim)
where T: ICombatant, GameObjectController
where U: ICombatant, GameObjectController
Although I probably wouldn't.
Presumably all ICombatants must also be GameObjectControllers? If so, you might want to make a new interface IGameObjectController and then declare:
interface IGameObjectController
{
// Interface here.
}
interface ICombatant : IGameObjectController
{
// Interface for combat stuff here.
}
class GameObjectController : IGameObjectController
{
// Implementation here.
}
class FooActor : GameObjectController, ICombatant
{
// Implementation for fighting here.
}
It is only syntactically possible if GameObjectController itself implements ICombatant; otherwise, I would say you have a design problem.
Interfaces are intended to define the operations available on some object; base classes identify what that object is. You can only pick one or the other. If accepting the ICombatant interface as an argument is not sufficient, it might indicate that ICombatant is defined too narrowly (i.e. doesn't support everything you need it to do).
I'd have to see the specifics of what you're trying to do with this object in order to go into much more depth.
What if you did this instead:
public class GameObjectControllerCombatant : GameObjectController, ICombatant
{
// ...
}
Then derive your combatant classes from this instead of directly from GameObjectController. It still feels to me like it's breaking encapsulation, and the awkwardness of the name is a strong indication that your combatant classes are violating the Single Responsibility Principle... but it would work.
Well, sort of. You can write a generic method:
public void ComputeAttackUpdate<T>(T attacker, AttackType type, T victim)
where T : GameObjectController, ICombatant
That means T has to satisfy both the constraints you need. It's pretty grim though - and if the attacker and victim could be different (somewhat unrelated) types, you'd have to make it generic in two type parameters instead.
However, I would personally try to go for a more natural solution. This isn't a situation I find myself in, certainly. If you need to regard an argument in two different ways, perhaps you actually want two different methods?
If you control all the classes in question, and if GameObjectController doesn't define any fields, the cleanest approach would be to define an IGameObjectController (whose properties and methods match those of GameObjectController) and an ICombatantGameObjectContoller (which derives from both IGameObjectController and ICombatant). Every class which is to be usable in situations that require both interfaces must be explicitly declared as implementing ICombatantGameObjectController, even though adding that declaration wouldn't require adding any extra code. If one does that, one can use parameters, fields, and variables of type ICombatantGameObjectController without difficulty.
If you can't set up your classes and interfaces as described above, the approach offered by Jon Skeet is a generally good one, but with a nasty caveat: to call a generic function like Mr. Skeet's ComputeAttackUpdate, the compiler has to be able to determine a single type which it knows is compatible with the type of the object being passed in and with all of the constraints. If there are descendants of GameObjectController which implement ICombatant but do not derive from a common base type which also implements GameObjectController, it may be difficult to store such objects in a field and later pass them to generic routines. There is a way, and if you need to I can explain it, but it's a bit tricky.

Categories

Resources