Difficultly combining Interfaces, Abstract class, Delegates, Generics and Covariance - c#

UPDATE:
Thanks to some help it seems to be a bug with Unity's compiler as it doesn't happen outside of Unity. I am currently submitting a bug report and I'll try and find a work around.
I originally posted this to reddit but I think I will need all the help I can get. Here is it copied over:
Not sure how it has come to this, but in order to maintain maximum extendability I have had to use all this techniques.
In short, this works
ICombatEffect<IEffectReturn> com = new TackleEffectBase(this);
but when I try this
ICombatEffect<IEffectReturn>[] EffectsArra = ICombatEffect<IEffectReturn>[]{new TackleEffectBase(this);}
or this
List< ICombatEffect<IEffectReturn>> EffectsList = new List< ICombatEffect<IEffectReturn>>{new TackleEffectBase(this)}
I get an ArrayTypeMismatchException.
Now for the details: (although I've condensed this a lot)
p
ublic interface ICombatEffect<out T> where T : IEffectReturn
{
T Effect(CombatProcessor combat);
}
public abstract class EffectTemplate<T1> : ICombatEffect<T1> where T1 : IEffectReturn
{
public abstract T1 Effect(CombatProcessor combat);
}
public abstract class DamageBaseTemplate : EffectTemplate<DamageBaseModifier>
{}
DamageBaseModifier : IEffectReturn
public class TackleEffectBase : DamageBaseTemplate
I've left out all of the functional stuff so I can let the types do the talking.
The premise is that I each ICombatEffect has an Effect Method. The Effect method must always have a return type that implements IEffectReturn interface. I need to preserve the return type of each ICombatEffect as it is used for sorting later.
Since I have quite a lot of functional code, I've put in the abstract class EffectTemplate. I've read a lot about this sort of style and the trick is to make the interface non-generic. I do not have that luxury unfortunately as sometimes I will not be using the template. So I have set up the interface with a covariant generic type. The abstract class sort of has its generic type linked so they will be the same. This took me a bloody long time to figure out and I was pretty disappointing when I couldn't get it to run today.
I'm no expert on generics but here is my theory on why I can create a single instance but not add that to a collection. When you declare the single instance it goes through and sets all the generics to the instance's type. For a collection, you can't really make its generics concrete, they are only there to see if it slots in.
I'm pretty ok with tearing this down for a better solution as long as it fulfills my needs, but I'm pretty darn curious about this solution. I thought myself so clever when I got all these cascading generic types to work, but alas.

Related

Conditional interface

For a project I'm on I'm unfortunately stuck with .NET 2.0 (many of our target machines are still Windows XP), which means no Optional type as Nuget's Optional library requires .NET 3.5.
Fortunately, rolling your own Optional type is pretty easy, but I've encountered one issue.
I would like something like the following:
class Optional<T> : (IComparable<Optional<T>> when T : IComparable<T>)
That is, I want my Optional type to implement Comparable, but only when the underlying type is Comparable.
The above syntax is sadly not valid, but is there a way achieve what I'm looking for?
Indeed this problem isn't confined to Optional, it will apply to any container type one wants to define that can implement it's internal type's interfaces.
I do realise I could do this:
class Optional<T>
class ComparableOptional<T> : Optional<T>, Comparable<ComparableOptional<T>>
where T : Comparable<T>
But this seems a bit silly, as then we really have to go down this rabbit hole:
class Optional<T>
class EquatableOptional<T> :
Optional<T>,
IEquatable<EquatableOptional<T>>
where T : IEquatable<T>
class ComparableOptional<T> :
EquatableOptional<T>,
IComparable<ComparableOptional<T>>,
IEquatable<ComparableOptional<T>>
where T : IComparable<T>
Furthermore, if T is Enumerable, Optional<T> can also be Enumerable (returning an empty enumerator if there is no value) so then we've got even more classes.
As Enumerable is orthogonal to Equatable and Comparable, we'd really need the following classes:
class Optional
class EquatableOptional
class ComparableOptional
class EnumerableOptional
class EnumerableEquatableOptional
class EnumerableComparableOptional
to cover all cases. Add another orthogonal interface and you've got 12 classes.
Is there a less messy approach that allows me to define interfaces conditionally? This seems like a common issue with any collection.
What you want to do infringes on the intention of how generics work in C#.
You're essentially arguing that type safety should be used as type possibility. Which is against the current C# ideology where you know a type's definition (and which methods and properties it exposes) for a fact.
The correct approach would be to have a second ComparableOptional<T> which derives from Optional<T> but adds an additional constraint:
class ComparableOptional<T> : Optional<T> where T : Comparable<T>
There is no benefit to your suggestion, other than the lazy approach of wanting to mash two different classes together. Even if the language would allow you to do so, I see no discernible benefit to this approach (compared to ComparableOptional<T>) but it does introduce a whole range of runtime errors that you can now encounter.
class Optional<T> : (IComparable<Optional<T>> when T : IComparable<T>) {}
Suppose everything works the way you expect it to.
var optionalPerson = new Optional<Person>() { Person = myPerson };
var optionalPerson2 = new Optional<Person>() { Person = myPerson2 };
int result = optionalPerson.CompareTo(optionalPerson2);
Should this work? In C# currently, it doesn't. But according to you, it should be able to if Person : IComparable<Person>. Your argument should be something like this:
Since the compiler sees me use the type Person : IComparable<Person>, it should be able to deduce that Optional<T> must now implement IComparable<T> and therefore the CompareTo() should be available.
The solidity of your argument rests solely on the fact that you know for a fact (at compile time) that the type you're using implements the needed interface.
But what about this code:
public void DoSomething<T>(Optional<T> opt1, Optional<T> opt2)
{
int result = opt1.CompareTo(opt2);
}
Should this work? You can't know, since you don't know which type will be used! Compounding the issue even further:
public void DoSomething(string optionalType, object opt1, object opt2)
{
var castObj = Convert.ChangeType(opt1, Type.GetType(optionalType)));
var castObj2 = Convert.ChangeType(opt2, Type.GetType(optionalType)));
int result = castObj .CompareTo(castObj2);
}
This method passes the used type as a string. So now you would expect the compiler to check the value of the string to figure out whether or not the generic type constraint of the type that is represented in the string implements a particular interface.
WHat if that string is retrieved from a database or external web service? Is the compiler now required to have an active database/web connection before it can decide whether your code is valid?
This is running out of hand.
Your likely counterarguments:
As long as I only use this method with types that implement IComparable<T>, the compiler should not throw an error. When I use a type that does not implement IComparable<T>, it should throw an error on the int result line.
That is not intuitive, and is going to lead to developer confusion.
The compiler should always assume that conditional generic type constraints are true.
So how would you handle mutually exclusive conditional generic type constraints, which logically will never both be true?
Welcome to the world of debugging hell. This is bad practice for the same reason that you shouldn't use dynamic over strongly typed approaches: it makes code considerably harder to maintain and develop.
Such an approach requires much more runtime testing to ensure that you haven't made a mistake somewhere that will blow up in your face. And runtime testing is a flawed approach.

Design an abstract class right way in C#

Given an abstract class A having a function sumBill(int a, int b). Now assume that you have 3 or 4 class extending class A and implementing their version of sumBill. And in various locations in the code you are making calls to sumBill with integer parameters.
Later on it is identified that the parameters need to be of type double rather than int. So now one has to go refactor all the places which make a call to sumBill to pass parameters of double data type.
So the question is what could the developer had done better to avoid such a problem in the first place.
Its a design pattern question.How to implement it in C#?
Nothing. Stuff like that happens. You gather requirements as good as you can and sometimes that just is not enough.
Something like this may work:
abstract class A{
public abstract T sumBill<T>(T t1, T t2);
}
class B : A {
public override T sumBill<T>(T t1, T t2) { /* your implementation of B here */ }
}
This "pattern" is called Generics. Have a look here.
However making every member generic only because it might be needed in the future is overkill. You probably won´t ever actually need it (YAGNI). In fact you cannot foresee those cases. You implement a software based on some requirement, if the requirement changes you´d change the software also.

Creating objects of different Types using a unified Signature

Imagine the following two classes:
class A
{
public A()
{
}
}
class B : A
{
public B()
{
}
}
Is it possible for me to define A, or alternatively an interface, in a way that forces class B to have a parameterless constructor? Or, more generalized, a constructor (or static method) that is able to create an instance of type B with a given signature?
I do not want to restrict class B to only be constructible using that signature, but I want to be sure that class B can be constructed with this signature (be it parameterless, or specifying certain parameters).
To be clear: I am not searching for a solution that would require me to use Reflection or any other method to figure that out at runtime (I don't have a problem with it, but it would make the code less readable, and generally seems like a bad idea in this case).
Is there a way to accomplish this?
I wrote a blog post that goes more in-depth about what I am trying to achieve here
There is no interface or base type that you can apply to the type to ensure it has a parameterless constructor. The only context in which you can make such a contraint is generic constraints:
public static void Foo<T>()
where T : new() {}
In such a case the only types that can be used with Foo must have a parameterless constructor.
You can define factory for instantiating objects of type A (and derived types):
interface IFactory<T> where T : A
{
T Create(int i);
T Create(string s);
// and so on...
}
and require factory implementation, when you want to create an object.
This will make sure calling code in compile time, that it tries to create an object with the given set of parameters.
Of course, there's nothing preventing from NotImplementedException from concrete IFactory<T> implementation at run-time.
This is a followup, since I did a little bit of research and at least managed to come up with an answer that is somewhat satisfying.
So after digging around a while and trying to figure out how the built-in serialization/deserialization in C# works, I found out that C# has a method called GetUninitializedObject(). This method seems like a hack, since it just avoids calling the constructor of the object in the first place, but it at least gives me a way to accomplish what I originally wanted: Being able to deserialize an object of an arbitrary type. Using this, I am able to use methods on the uninitialized created objects (and forcing their implementation via an interface).
I find this to be fitting my needs, although it does not do what I originally wanted to, it allows me to implement a pattern that works for my purposes.
Best Regards

Using The Interface Methods I Want Based On The Implementation

I have two basic interface-related concepts that I need to have a better
understanding of.
1) How do I use interfaces if I only want to use some of the interface
methods in a given class? For example, my FriendlyCat class inherits from
Cat and implements ICatSounds. ICatSounds exposes MakeSoftPurr() and
MakeLoudPurr() and MakePlayfulMeow(). But, it also exposes MakeHiss()
and MakeLowGrowl() - both of which I don't need for my FriendlyCat class.
When I try to implement only some of the methods exposed by the interface
the compiler complains that the others (that I don't need) have not been
implemented.
Is the answer to this that I must create an interface that only contains
the methods that I want to expose? For example, from my CatSounds class, I
would create IFriendlyCatSounds? If this is true, then what happens when
I want to use the other methods in another situation? Do I need to create
another custom-tailored interface? This doesn't seem like good design to me.
It seems like I should be able to create an interface with all of the
relevant methods (ICatSounds) and then pick and choose which methods I
am using based on the implementation (FriendlyCat).
2) My second question is pretty basic but still a point of confusion for
me. When I implement the interface (using Shift + Alt + F10) I get the interface's
methods with "throw new NotImplementedException();" in the body. What
else do I need to be doing besides referencing the interface method that
I want to expose in my class? I am sure this is a big conceptual oops, but
similar to inheriting from a base class, I want to gain access to the methods
exposed by the interface wihtout adding to or changing them. What is the
compiler expecting me to implement?
-- EDIT --
I understand #1 now, thanks for your answers. But I still need further elaboration
on #2. My initial understanding was that an interface was a reflection of a the fully
designed methods of a given class. Is that wrong? So, if ICatSounds has
MakeSoftPurr() and MakeLoudPurr(), then both of those functions exist in
CatSounds and do what they imply. Then this:
public class FriendlyCat: Cat, ICatSounds
{
...
public void ICatSounds.MakeLoudPurr()
{
throw new NotImplementedException();
}
public void ICatSounds.MakeSoftPurr()
{
throw new NotImplementedException();
}
}
is really a reflection of of code that already exists so why am
I implementing anything? Why can't I do something like:
FriendlyCat fcat = new FriendlyCat();
fcat.MakeSoftPurr();
If the answer is, as I assume it will be, that the method has no
code and therefore will do nothing. Then, if I want these methods
to behave exactly as the methods in the class for which the interface
is named, what do I do?
Thanks again in advance...
An interface is a contract. You have to provide at least stubs for all of the methods. So designing a good interface is a balancing act between having lots of little interfaces (thus having to use several of them to get anything done), and having large, complex interfaces that you only use (or implement) parts of. There is no hard an fast rule for how to choose.
But you do need to keep in mind that once you ship your first version of the code, it becomes a lot more difficult to change your interfaces. It's best to think at least a little bit ahead when you design them.
As for implementation, it's pretty common to see code that stubs the methods that aren't written yet, and throws a NotImplemented exception. You don't really want to ship NotImplemented in most cases, but it's a good get around the problem of not having the code compile because you havn't implemented required parts of the interface yet.
There's at least one example in the framework of "deliberately" not implementing all of an interface's contract in a class: ReadOnlyCollection<T>
Since this class implements IList<T>, it has to have an "Insert" method, which makes no sense in a read-only collection.
The way Microsoft have implemented it is quite interesting. Firstly, they implement the method explicitly, something like this:
public class ReadOnlyCollection<T> : IList<T>
{
public void IList<T>.Insert(int index, T item)
{
throw new NotSupportedException();
}
/* ... rest of IList<T> implemented normally */
}
This means that users of ReadOnlyCollection<T> don't see the Insert method in intellisense - they would only see it if it were cast to IList<T> first.
Having to do this is really a hint that your interface hierarchy is a bit messed up and needs refactoring, but it's an option if you have no control over the interfaces (or need backwards compatibility, which is probably why MS decided to take this route in the framework).
You have to implement all the methods in your interface. Create two interfaces, IHappyCatSounds and IMeanCatSounds, split out those methods. Don't implement IMeanCatSounds in FriendlyCat, because a friendly cat is not a mean cat. You have to think about an interface as a contract. When you write the interface, you are guaranteeing that every class that implements the interface will have those members.
It throws a NotImplementedException because you haven't implemented it yet. The compiler is expecting you to implement the code that would be completed when the cat purrs, meows or hisses. An interface doesn't have code in it. It's simply nothing more than a contract for any class that implements it, so you can't really "access the code" the interface implements, because the interface doesn't implement any code. You implement the code when you inherit from the interface.
For example:
// this is the interface, or the "contract". It guarantees
// that anything that implements IMeowingCat will have a void
// that takes no parameters, named Meow.
public class IMeowingCat
{
void Meow();
}
// this class, which implements IMeowingCat is the "interface implementation".
// *You* write the code in here.
public class MeowingCat : IMeowingCat
{
public void Meow
{
Console.WriteLine("Meow. I'm hungry");
}
}
I'd strongly suggest picking up a copy of The Object Oriented Thought Process, and read it through in it's entirety. It's short, but it should help you to clear things up.
For starters, though, I'd read this and this.
Imagine that you could "pick and choose." For example, suppose you were allowed to not implement ICatSounds.MakeHiss() on FriendlyCat. Now what happens when a user of your classes writes the following code?
public ICatSounds GetCat()
{
return new FriendlyCat();
}
ICatSounds cat = GetCat();
cat.MakeHiss();
The compiler has to let this pass: after all, GetCat is returning an ICatSounds, it's being assigned to an ICatSounds variable and ICatSounds has a MakeHiss method. But what happens when the code runs? .NET finds itself calling a method that doesn't exist.
This would be bad if it were allowed to happen. So the compiler requires you to implement all the methods in the interface. Your implementation is allowed to throw exceptions, such as NotImplementedException or NotSupportedException, if you want to: but the methods have to exist; the runtime has to be able to at least call them, even if they blow up.
See also Liskov Substitution Principle. Basically, the idea is that if FriendlyCat is an ICatSounds, it has to be substitutable anywhere an ICatSounds is used. A FriendlyCat without a MakeHiss method is not substitutable because users of ICatSounds could use the MakeHiss method but users of FriendlyCat couldn't.
A few thoughts:
Interface Separation Principle. Interfaces should be as small as possible, and only contain things that cannot be separated. Since MakePlayfulMeow() and MakeHiss() are not intrinsically tied together, they should be on two separate interfaces.
You're running into a common problem with deep inheritance trees, especially of the type of inheritance that you're describing. Namely, there's commonly three objects that have three different behaviors in common, only none of them share the same set. So a Lion might Lick() and Roar(), a Cheetah might Meow() and Lick(), and an AlienCat might Roar() and Meow(). In this scenario, there's no clear inheritance hierarchy that makes sense. Because of situations like these, it often makes more sense to separate the behaviors into separate classes, and then create aggregates that combine the appropriate behaviors.
Consider whether that's the right design anyway. You normally don't tell a cat to purr, you do something to it that causes it to purr. So instead of MakePlayfulMeow() as a method on the cat, maybe it makes more sense to have a Show(Thing) method on the cat, and if the cat sees a Toy object, it can decide to emit an appropriate sound. In other words, instead of thinking of your program as manipulating objects, think of your program as a series of interactions between objects. In this type of design, interfaces often end up looking less like 'things that can be manipulated' and more like 'messages that an object can send'.
Consider something closer to a data-driven, discoverable approach rather than a more static approach. Instead of Cat.MakePlayfulMeow(), it might make more sense to have something like Cat.PerformAction(new PlayfulMeowAction()). This gives an easy way of having a more generic interface, which can still be discoverable (Cat.GetPossibleActions()), and helps solve some of the 'Lions can't purr' issues common in deep inheritance hierarchies.
Another way of looking at things is to not make interfaces necessarily match class definitions 1:1. Consider a class to define what something is, and an interface as something to describe its capabilities. So whether FriendlyCat should inherit from something is a reasonable question, but the interfaces it exposes should be a description of its capabilities. This is slightly different, but not totally incompatible, from the idea of 'interfaces as message declarations' that I suggested in the third point.

Cannot Convert Derived Class to Base Class

I am working on a transportation problem and cannot leap this hurdle. I am unable to convert the derived class StopsVisited to its base class Stops. The base class Stops is a collection of Stop. The derived class StopsVisited is a collection of StopVisited.
The element StopVisited derives from Stop (definitions not shown).
I have a non-generics workaround where I simplly derive StopsVisited from Stops, but the generics afford me more felixibility. I've tried to reduce it to its simplest form.
Base
public abstract class Stops<T> where T : Stop
{
}
Derived
public class StopsVisited : Stops<StopVisited>
{
}
The problem:
Stops<Stop> stops = new StopsVisited();
Gives me a
Error 1 Cannot implicitly convert type 'StopsHeirarchy.StopsVisited' to 'StopsHeirarchy.Stops'
Any help is appreciated.
StopsVisited is not a subtype of Stops<Stop>; it's a subtype of Stops<StopVisited>, which is an entirely different thing. I agree with duffymo that subtyping is the wrong approach to your problem, but the specific feature you're asking about is called "covariance" or "output-safe" in C# 4; you can read about it here.
Personally, I wouldn't use inheritance to say that a Stop has been visited. I'd have a boolean data member to say that a Stop had been visited. It seems like a binary attribute - you've either been visited or you haven't.
Inheritance ought to be about different behaviors. Unless you can say that a visited Stop somehow behaves differently, I would advise against inheritance in this design.
C# 4.0 solves this problem by modifying the CLR to support it.
In the meantime, have an IStops interface (non-generic) and convert to it.

Categories