74

Using Resharper 4.1, I have come across this interesting warning: "Access to a static member of a type via a derived type". Here is a code sample of where this occurs:

class A {
    public static void SomethingStatic() {
       //[do that thing you do...]
    }
}

class B : A {
}

class SampleUsage {
    public static void Usage() {
        B.SomethingStatic(); // <-- Resharper warning occurs here
    }
}

Does anybody know what issues there are (if any) when making use of A's static members via B?

Swim
  • 1,561
  • 1
  • 12
  • 18

4 Answers4

85

One place where it might be misleading is when the static is a factory method, e.g. the WebRequest class has a factory method Create which would allow this type of code to be written if accessed via a derived class.

var request = (FtpWebRequest)HttpWebRequest.Create("ftp://ftp.example.com");

Here request is of type FtpWebRequest but it's confusing because it looks like it was created from an HttpWebRequest (a sibling class) even though the Create method is actually defined on WebRequest (the base class). The following code is identical in meaning, but is clearer:

var request = (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com");

Ultimately there's no major problem accessing a static via a derived type, but code is often clearer by not doing so.

Greg Beech
  • 133,383
  • 43
  • 204
  • 250
  • This is an issue I have never thought of before. Thanks Greg! – Swim Mar 18 '09 at 21:25
  • great explanation, it was really helpful. First result on google too ^^ – marcgg Jul 02 '09 at 18:07
  • 1
    Yeah, fun too when somebody thinks that enough is enough and does implement `Create` on `HttpWebRequest`, hiding the method. Recompile, code break. Many programming languages still think the world stays put. – Maarten Bodewes Nov 23 '15 at 22:20
30

B.SomethingStatic() makes the statement that SomethingStatic is a member of B. This is not true. SomethingStatic is unequivocally a member of A. The fact that it's accessible unqualified to members of B (as if it were a member of B) is a matter of convenience. The fact that it's accessible when qualified with a B is, IMO, a mistake.

P Daddy
  • 28,912
  • 9
  • 68
  • 92
  • I think a subclass should always inherit every property of a superclass. Especially for the project I'm on right now, It's super helpful with factory patterns. – NullVoxPopuli Aug 26 '15 at 14:10
  • I disagree. I have a valid case when the current behavior is beneficial. Here is the idea: `class Validator : ValidatorBase {}`. Usage: `Validator.CheckNonEmpty(str)`. Compare this to `ValidatorBase.CheckNonEmpty(str)`. – Gebb Feb 09 '17 at 12:35
  • @Gebb: I'm afraid I don't see your point. So you've designed a class hierarchy that's hard to type. How does that invalidate what I said? If it were me, I would expect `Validator.CheckNonEmpty`, which appears to be a static member of the `Validator` class, to behave differently from `ValidatorBase.CheckNonEmpty`, which is provided by a different type. It doesn't, which is confusing. And if you had another derived class, would you call `CheckNonEmpty` on that, too? The fact that this misfeature might save you some typing in a certain situation doesn't make it a good feature. – P Daddy Feb 11 '17 at 17:17
  • @PDaddy: It's not the typing that matters, it's the readability. It does appear that `CheckNonEmpty` belongs to the `Validator` class, which it doesn't, but that doesn't matter as long as it's obvious what it does. – Gebb Feb 11 '17 at 18:30
15

It's not a warning, usually, just a suggestion. You're creating a dependency on something unnecessarily.

Suppose you later decide that B doesn't need to inherit A. If you follow Resharper's advice, you won't need to modify that line of code.

Daniel Earwicker
  • 114,894
  • 38
  • 205
  • 284
  • 2
    you'd have the same problem with instance methods, too. By all this logic, why inherit anything? or am I missing something? – NullVoxPopuli Aug 26 '15 at 22:21
  • @NullVoxPopuli - There are those who do recommend avoiding implementation inheritance altogether. Several popular Java and C# books suggest this (see also this paper: http://www.isase.us/wisr3/7.pdf). But in any case, if you do have an instance method `Foo` in `A`, then given an instance of `B` referred to by variable `b`, you don't have the same freedom as in the static case to say "where" `Foo` should be looked up. You have to start with `b`, whatever you do. So it's not really the same as with statics. – Daniel Earwicker Aug 27 '15 at 22:03
2

Yeah I've seen this too, I've always assumed it was just warning me because it was unnecessary. A.SomethingStatic(); would do the same thing.

Ray
  • 45,695
  • 27
  • 126
  • 169