在派生类型上使用类的静态成员?


73

使用Resharper 4.1,我遇到了一个有趣的警告:“通过派生类型访问类型的静态成员”。这是发生这种情况的代码示例:

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
    }
}

有人知道通过B使用A的静态成员时有什么问题(如果有)吗?

Answers:


84

一个可能引起误解的地方是静态变量是工厂方法,例如,WebRequest类具有工厂方法Create,如果通过派生类进行访问,则将允许编写这种类型的代码。

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

request是类型,FtpWebRequest但是令人困惑,因为HttpWebRequest即使Create方法实际上是在WebRequest(基类)上定义的,它看起来也是从(同级类)创建的。以下代码的含义相同,但更清楚:

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

最终,通过派生类型访问静态对象没有大问题,但是通过这样做通常可以使代码更清晰。


这是我从未想过的问题。谢谢格雷格!
游泳

很好的解释,真的很有帮助。谷歌上的第一个结果也^^
marcgg

1
是啊,乐趣,当有人认为太适可而止但实现CreateHttpWebRequest,隐藏的方法。重新编译,代码中断。许多编程语言仍然认为世界仍然存在。
Maarten Bodewes,2015年

30

B.SomethingStatic()使得该声明SomethingStatic是其成员B。这不是真的。 SomethingStatic毫无疑问是的成员A。方便其访问B(如果它是的成员B)不合格的事实。BIMO合格后就可以访问它,这是一个错误。


我认为子类应该始终继承超类的每个属性。特别是对于我现在正在进行的项目,它对工厂模式非常有帮助。
NullVoxPopuli

我不同意。我有一个有效的案例,说明当前的行为是有益的。这里的理念是:class Validator : ValidatorBase<ThrowStrategy> {}。用法:Validator.CheckNonEmpty(str)。将此与进行比较ValidatorBase<ThrowStrategy>.CheckNonEmpty(str)
Gebb's

@Gebb:恐怕我看不到你的意思。因此,您设计了一个很难键入的类层次结构。这如何使我所说的无效?如果是我,我希望Validator.CheckNonEmpty它看起来Validator像是类的静态成员,其行为与ValidatorBase<ThrowStrategy>.CheckNonEmpty由不同类型提供的有所不同。事实并非如此,这令人困惑。而且,如果您还有另一个派生类,您也可以调用CheckNonEmpty它吗?这种不适当的功能可能会在某些情况下为您节省一些打字的事实,但这并不意味着它是一个好功能。
P Daddy

@PDaddy:无关紧要的是打字,而是可读性。它看起来确实CheckNonEmpty属于Validator该类,但不是,但是只要它做什么就无关紧要。
Gebb's

15

通常这不是警告,只是建议。您正在不必要地创建对某些内容的依赖。

假设您以后决定B不需要继承A。如果遵循Resharper的建议,则无需修改该行代码。


2
实例方法也会遇到同样的问题。按照所有这些逻辑,为什么要继承任何东西?还是我错过了什么?
NullVoxPopuli

@NullVoxPopuli-有些人建议完全避免实现继承。几本流行的Java和C#书籍提出了这一建议(另请参见本文:isase.us/wisr3/7.pdf)。但在任何情况下,如果你有一个实例方法FooA,然后给出一个实例B可变称b,你没有同样的自由,在静态情况下说“其中”Foo应该抬起头来。b无论您做什么,都必须从开始。因此,它与静态方法并不完全相同。
Daniel Earwicker 2015年

2

是的,我也看到了这一点,我一直认为这只是警告我,因为这是不必要的。A.SomethingStatic();会做同样的事情。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.