[...]
Now that I write this more
clearly I start to understand that the compiler does not know that
another object might be sent to thismethod.
I believe that is true. What I was playing with regarding constraints
was having both T and Wrapper<T> inherit a common interface, so that
they could be treated the same. But in that case, all that the compiler
knows still is that they implement the common interface. That means the
"manager"methodwould have to be changed to take an object with the
common interface as a parameter, rather than using the overload. That's
possible, but it introduces new complexities itself.
The basic issue here is that with generics, the compiler needs to know
whatmethodis going to be called when it compiles the code. More
problematically, it can't defer that until some concrete use of thegeneric. Everything the compiler needs to know must be known when
compiling thegenericclassitself (considergenericclasses implemented
in a pre-compiled assembly, like those already in .NET, for example),
and generics don't provide any way for you to relate T and Wrapper<T> in
a way that makes sense at compile time.
In the error you're getting, the compiler has selected an overload
already -- it has to pick the overload at compile time -- and then it
finds that it doesn't have enough information to consistently ensure
that the parameter passed to the overload is always what it needs. Thus
the error.
What I need is to be able
to tell it that E is either T or Wrapper<T> but I don't think this is
possible. I suppose I will need to use overloaded methods here but I
was trying to avoid that because all of the code is actuallygeneric
for thatmethodon the assumption you know it is only one of these 2
types that will be sent in
(
If anyone has any further advice I would appreciate it.
I agree with your assessment that exactly what you want isn't possible.
However, I will say that often when I find that I'm unable to do
something with generics that I'd like to do, if I take a step back and
try to figure out what it is about my underlying design that imposes the
desire to use generics in a specific way, I discover that my underlying
design is leading me down a path that's itself not a desirable one.
In a way, the barricade I run into with respect to thegeneric
implementation is actually a big warning flag saying that my basic
design could be improved.
Whether this is the case in your situation, I don't know. You would
have to look at a wider picture than what you've shown here, I think.
Just as an example though, do you really need to put your "value-added"
stuff in ageneric"Wrapper<>"class? Or does that Wrapper<>classneed
to be structured in exactly the way it is? I haven't thought about this
much, but if Wrapper<T> actually inherited T, then you could always pass
a Wrapper<T> to anymethodthat took a T. You wouldn't need to use
overloads, but the methods would have to check the object passed in to
see whether it's a Wrapper<T> or just a plain T.
Anyway, that's just an example...if that doesn't actually work, there
are other ways to create a data structure that can be, essentially "T,
or T+other stuff" in a way that is more compatible with generics (that
is, more of the logic happens at run-time, getting around the problem
that at compile time there's not enough information to resolve ambiguities).
Pete