syntax subtelty ....

  • Thread starter Thread starter Lloyd Dupont
  • Start date Start date
L

Lloyd Dupont

I'm creating a DataProvider, I begin to have something working and was about
to implement IDbParameter. Now I discover that there is a C# subtelty I
don't master:

I wrote

public class FileMakerCommand : IDbCommand
{
.......
public FileMakerDataParameter Parameters
{
get { /* return something */ }
}
....
}
however this is incorrect because IDbCommand require Parameters to return an
IDataParameterCollection

then I wrote (half remembering something I read a while ago):
public class FileMakerCommand : IDbCommand
{
.......
FileMakerDataParameter IDbCommand.Parameters
{
get { /* return something */ }
}
public FileMakerDataParameter Parameters
{
get { /* return something */ }
}
....
}
and it worked.
now I wonder, when this package accessor (the IDbCommand.Parameters one) get
called ? when you cast the instance as just a IDbCommand ? never ? always ?
sometimes in the afternoon ?

could anyone shed some light ?

thanks :-)
 
Jon Skeet said:
IDataParameterCollection IDbCommand.Parameters
?
oh, well, my mistake, yes I meant what you said !

This is called explicit interface implementation. Basically, if someone
has:

FileMakerCommand foo = ...;
FileMakerDataParameter p = foo.Parameters;

they'll call your public property. If they have

IDbCommand bar = foo;
IdataParameterCollection p2 = bar.Parameters;

they'll call the explicit interface implementation. The type of the
reference (rather than the type of the actual object it refers to) is
used here. Personally I don't like explicit interface implementation -
it feels ugly to me.
thanks :-)

however I disagree with your 'ugly' statement. basically alll you need is
your interface implementation to return the specific implementation.

but it's indeed very usefull for type safety and nice implementation. once I
design a kind of TreeModel which has typed TreeNode and implemented all
method of IList but 'object this[int]' because it returned a typed 'TreeNode
this[int]'.
on the other hand, make my TreeModel an IList would opens me a vast amount
of possibilities.
At this time I didn't think of the specific implemenation and I was very
worried not to implement IList, but type safety was a must ...
and I'm very happy I could have both !

Anyway, thanks :-)
 
Thanks again for your explanation :-)

BTW here is a better explanation why interface implementation IS very good.

take simple example, you want to write a class like that:
class BunchOfStuff
{
public StuffEnumerator GetEnumerator() { /* return something */ }
}

and you woul like to implement IEnumerable but it's not possible because
GetEnumerator() has the wrong signature. on the other hand you want to keep
your strong typing.

is it hopeless ?
no !

thanks to interface specific implementation you could write:
class BunchOfStuff : IEnumerable
{
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
public StuffEnumerator GetEnumerator() { /* return something */ }
}

isn't that wonderfull ?
and it's not a marginal case, I often have such problem and I'm happy I just
find a solution !
 
Lloyd Dupont said:
however I disagree with your 'ugly' statement. basically alll you need is
your interface implementation to return the specific implementation.

But I believe it's ugly because it shouldn't matter what the type of
the reference is - it should only be the type of the *object* which
matters. This is the only place in C# (as far as I'm aware) which
violates that.
but it's indeed very usefull for type safety and nice implementation. once I
design a kind of TreeModel which has typed TreeNode and implemented all
method of IList but 'object this[int]' because it returned a typed 'TreeNode
this[int]'.

Generics are a far nicer way of implementing this - I'd rather wait
until the next version of the framework which has generics than use
explicit interface implementation. As I said though, it's only my
personal view.
on the other hand, make my TreeModel an IList would opens me a vast amount
of possibilities.
At this time I didn't think of the specific implemenation and I was very
worried not to implement IList, but type safety was a must ...
and I'm very happy I could have both !

Your call, obviously :)
 
Lloyd Dupont said:
Thanks again for your explanation :-)

BTW here is a better explanation why interface implementation IS very good.

<snip>

It's still basically making up for the lack of covariant return types,
and it's not a very nice solution to that problem, compared with
generics. As I say, it's nasty (to my mind) when the type of the
*reference* affects which *instance* method is called, rather than
solely the type of the object.

(Now I think of it, there is something which is *slightly* similar -
operator overloading. No instance methods involved, but still results
which can be surprising to the unwary.)
 
Back
Top