Rationale for CS0536?

  • Thread starter Thread starter elvis_the_king
  • Start date Start date
E

elvis_the_king

Hi all,

I'm still new to C# so maybe someone can explain me the rationale for

CS0536: 'someClass' does not implement interface member
'some.Interface.Member()'. 'someClass.Member()' is either static, not
public, or has the wrong return type.

Why can't I have a class implementing the interface with static
methods? IIRC, in Java or C++ it's possbile to call a static member
either through the class name (someClass::Member()) or through an
object instance.

My motivation is that I have to work with mathematical/stochastical
distributions. Thus I basically have an

interface Distribution {
double probability(double x);
}

and several classes implementing it. Additionally, there are some
calculation methods that return "Distribution"s, so they give me
instances of Distributions. Allright so far :)

Now there's the standard normal distribution. As you might remember
from your math classes, it does not depend on any specific parameters
and is commonly used. So I would like to call
StdNormalDistribution::probability() and the like in many places.
Additionally, StdNormalDistribution is_a Distribution and may be
returned by the calculation methods mentioned above. So it would be
nice if StdNormalDistribution could be returned as an instance as well
as being called statically when needed.

Is there a "nice" way to work around this in C#? Is my oop design
broken? Am I overlooking a good reason for doing it as-is?

[Of course the "other way round" - having the interface static but the
instance non-static cannot work; I'm not even sure if "static" makes
sense in an interface?]

Thanks a lot,
Matthias
 
Matthias,

You could use static methods to implement interfaces, but you would have
to do it in a roundabout way, calling your static methods from the methods
on the instance.

Of course, that isn't what you want. Interfaces are closely tied to
objects (instances) not types (classes). While you could have interfaces
that are implemented with static properties, fields, and methods, it would
be just a roundabout way of encapsulating the functionality in an instance
(you would access static methods, which access local variables and static
fields, etc, etc).

What you should do is make your StdDeviation class a singleton class,
and expose the instance as an implementation of the Distribution interface
(which should be named IDistribution, as recommended by the public naming
conventions) through an Instance property (or GetInstance method). This
way, you have one instance which implements the interface.

Hope this helps.
 
Nicholas,

first of all, thanks for the quick reply and pointing me to recommended
naming conventions :).
What you should do is make your StdDeviation class a singleton class,
and expose the instance as an implementation of the Distribution interface
(which should be named IDistribution, as recommended by the public naming
conventions) through an Instance property (or GetInstance method). This
way, you have one instance which implements the interface.

If I understand you correctly, methods that return "IDistribution"s and
want to return a standard normal distribution would "return
StdNormalDistribution.getInstance();".

Other clients would just call e. g.
"StdNormalDistribution.getInstance().probability(...)" for the
calculations they need.

Still, this seems to be a cumbersome way to accomplish that behaviour.
So, to come back to the basic question - why did they make it the way
it is? Any case where there would be ambiguities when calling static
members via instances?

Best regards,
Matthias
 
Matthias,

No, you would just do something like this:

// The distribution implementation.
IDistrubtion distribution = null;

// Set the distribution implementation here.
// For default, use the StdNormalDistribution.
distribution = StdNormalDistribution.Instance;

However, this is why you have class factories. You would have an
enumeration like so:

public enum DistributionImplementation
{
Standard,
Other1,
Other2
}

And then a static method like this:

public static IDistrubition
CreateDistributionImplementation(DistributionImplementation implementation)
{
// Based on the value, create the implementation.
switch (implementation)
{
case DistributionImplementation.Standard:
return new StdNormalDistribution();

case Other1:
return new Other1();
}
}

I wouldn't make a singleton in this instance, it kind of defeats the
reason for having a singleton in this instance.
 
Hi all,

I'm still new to C# so maybe someone can explain me the rationale for

CS0536: 'someClass' does not implement interface member
'some.Interface.Member()'. 'someClass.Member()' is either static, not
public, or has the wrong return type.

Why can't I have a class implementing the interface with static
methods? IIRC, in Java or C++ it's possbile to call a static member
either through the class name (someClass::Member()) or through an
object instance.

My motivation is that I have to work with mathematical/stochastical
distributions. Thus I basically have an

interface Distribution {
double probability(double x);
}

and several classes implementing it. Additionally, there are some
calculation methods that return "Distribution"s, so they give me
instances of Distributions. Allright so far :)

Now there's the standard normal distribution. As you might remember
from your math classes, it does not depend on any specific parameters
and is commonly used. So I would like to call
StdNormalDistribution::probability() and the like in many places.
Additionally, StdNormalDistribution is_a Distribution and may be
returned by the calculation methods mentioned above. So it would be
nice if StdNormalDistribution could be returned as an instance as well
as being called statically when needed.

Is there a "nice" way to work around this in C#? Is my oop design
broken? Am I overlooking a good reason for doing it as-is?

[Of course the "other way round" - having the interface static but the
instance non-static cannot work; I'm not even sure if "static" makes
sense in an interface?]

Thanks a lot,
Matthias

Hi Matthias,
you should use implicit interface implementation:

class StdNormalDistribution : IDistribution
{
//This is the interface-implemantation for call
//This member will only be callable on an expression of type
//IDistribution
double IDistribution.propability (double x)
{
//Simply calls the static method
return this.propability(x);
}

//This is the static method for call without instance
public static double propability(double x)
{
//Performs the calculation
return .........;
}
}

Best Regars
Christof
 
Hm :) Actually, the IDistribution does not only contain probability()
but a lot of other things. That would be a lot of code - two members
for each Interface element, just to keep "two versions" of the same
thing, with one of both being the implementation and the other one just
dispatching...

So why is all the hassle necessary? I still don't understand the
rationale for this language specification detail.

Best regards,
Matthias
 
I'm still new to C# so maybe someone can explain me the rationale for

CS0536: 'someClass' does not implement interface member
'some.Interface.Member()'. 'someClass.Member()' is either static, not
public, or has the wrong return type.

Why can't I have a class implementing the interface with static
methods? IIRC, in Java or C++ it's possbile to call a static member
either through the class name (someClass::Member()) or through an
object instance.

You certainly can in Java, although it's bad form to do so as it hides
the fact that it's actually a static method. This can easily lead to
bugs.

You *can't* do what you want in Java, however, in terms implementing an
interface with a static method.

I think I'd personally have some a separately named method in
StdNormalDistribution which made it obvious that it was basically a
constant - then call that from the method implementing the interface.
 
Still, this seems to be a cumbersome way to accomplish that behaviour.
So, to come back to the basic question - why did they make it the way
it is? Any case where there would be ambiguities when calling static
members via instances?

It is this way because it distinguishes between an action on the type and on
the instance itself. Jon Skeet, another MVP who wanders these groups, likes
to use Thread.Sleep as an example

Thread t = ...;
t.Sleep(10);

What does that look like its doing to you? To me it looks like its putting
the thread referenced by t to sleep, however, its not. It is putting the
current thread to sleep since Sleep is a static method. If you did around
you will find alot of examples where that occurs.

Another example might be:

string s = "cat";

s = s.Concat("apple", "orange");
Console.WriteLine(s);

The expected result of that operation looks like it should be
"catappleorange", but it is actually "appleorange" since Concat is static
and does not act on the original variable. By not allowing statics to be
called through instances you don't have issues like that.
 
Hi,

Is there any other possible distribution that expect something else than
either a double or nothing?
If not you could simple make both your stochastical as Normal to implement
double probability(double x);

The normal will simply ignore the parameter.




cheers,
 
Daniel said:
Thread t = ...;
t.Sleep(10);

What does that look like its doing to you? To me it looks like its putting
the thread referenced by t to sleep, however, its not. It is putting the
current thread to sleep since Sleep is a static method. If you did around
you will find alot of examples where that occurs.

Well, that sounds reasonable; but I would just consider that a bad
design or even naming problem, nothing that would have to be
interdicted by the language itself?

Besides that - I think I've seen compiler errors that say static
members have to be qualified with a type name, not an instance
(CS0176)? But probably that gets off-topic here.
 
Well, that sounds reasonable; but I would just consider that a bad
design or even naming problem, nothing that would have to be
interdicted by the language itself?

It is not bad design, calling statics via instances is a bad idea. Allowing
what Java and C++ does and waht you suggested causes that problem.
Besides that - I think I've seen compiler errors that say static
members have to be qualified with a type name, not an instance
(CS0176)? But probably that gets off-topic here.

Weren't you just asking why the compiler didn't let you call static methods
through instances and now you are using the compilers actual behavior as an
argument against my reason for the compiler acting that way? That just
doesn't make any sense, to be honest.
 
I tried the "implicit interface implementation" (implicit? explicit?)
approach Christof suggested; the explicit naming seems to be necessary
to avoid clashing the members, as both the "static" version and the
"instance" version have the same signatures. Still, that limits me to
accessing the StdNormalDistribution through IDistribution type
references, but I was thinking about the following cases:

/* Some generic calculation function will just return "IDistribution"
as type */
IDistribution d = new StdNormalDistribution();
Console.WriteLine("{0:0.00000}", d.cumulativeProbability(1.96));

/* Code inside some generic calculation function knows that it will use
a
* StdNormalDistribution. It uses a stronger qualified type - it still
can
* return it as a IDistribution later on. */
StdNormalDistribution n = new StdNormalDistribution();
Console.WriteLine("{0:0.00000}", n.cumulativeProbability(1.96));

/* As a third case, some generic calculation function just needs to
know
* a certain value of the cdf; a static call seems reasonable. */
Console.WriteLine("{0:0.00000}",
StdNormalDistribution.cumulativeProbability(1.96));

Now that still fails for the second case - the first one will use the
explicit interface implementation, the last one the static members; but
the second one gives another CS0176 ("Static member 'member' cannot be
accessed with an instance reference; qualify it with a type name
instead").

I almost get the feeling that I am basically misunderstanding the
concept of "interfaces" :). I thought having an IDistribution and
returning that type from methods is a contractual thing and means "I
will return something you can make a call to 'probability(double)' on."
Now in most cases, the "thing" returned is a specific instance of some
type of distribution; but it could also be an instance of a
StdNormalDistribution.

In the latter case, calling "probability(...)" would get the static
member - but the client would not care. He accessed the static member
through an instance, but no matter, the "contract" can be fulfilled.

Having the static member allows for using it in calculations without
having to create instances everywhere first - just call
StdNormalDistribution.probability() directly. But I still want to be
able to pass instances around as the result of calculations :).
 
Weren't you just asking why the compiler didn't let you call static methods
through instances and now you are using the compilers actual behavior as an
argument against my reason for the compiler acting that way? That just
doesn't make any sense, to be honest.

I got you wrong. I thought code snippet you provided was "valid" C#
that could easily be misunderstood. I was wondering why it was possible
to call t.Sleep() as it was against what I expected and asking for :).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top