有没有让基类在C#中使用派生类的静态变量?像这样:
class Program
{
static void Main(string[] args)
{
int Result = DerivedClass.DoubleNumber();
Console.WriteLine(Result.ToString()); // Returns 0
}
}
class BaseClass
{
public static int MyNumber;
public static int DoubleNumber()
{
return (MyNumber*2);
}
}
class DerivedClass : BaseClass
{
public new static int MyNumber = 5;
}
我试图让它返回10,但我得到0。
这里是我使用它的地方:我有一个名为ProfilePictures的类,它带有一个名为GetTempSavePath的静态函数,它将用户id作为参数,并返回临时文件的物理路径。路径库是一个名为TempPath的静态变量。由于我在多个项目中使用此类并且它们具有不同的TempPath,因此我创建了一个派生类,将该变量设置为项目的路径。
答案 0 :(得分:6)
除了已经指出的事实......静态变量被绑定或绑定到声明它们的特定类,并且不能被覆盖。覆盖/多态性需要实例才能工作。
您的问题可以通过改变设计来解决。
string ProfilePictures.GetTempSavePath(SomeType UserId, string sBasePath)
如果只需要这2个变量来计算返回值,则可以将其保留为实用程序/静态方法。现在,您可以提供不同的基本路径..
现在看来,您需要在多个项目(具有固定基本路径)中使用此类,并对基本路径进行硬编码,这样您就不必为每个调用指定它。
类型/类层次结构应基于行为定义,而不是基于数据。变量可以处理数据的变化。因此我建议将basepath值保存为静态成员变量,该变量是从资源文件初始化的(DoubleClick项目属性节点>设置>添加新设置文件>添加新的设置名为BasePath - string - 应用程序范围 - VALUE = C:\Users
)。现在你只需要为每个项目调整app.config文件,不需要更改代码,不需要硬编码,也不需要多种类型。
public class PathHelper
{
static string _sBasePath;
static PathHelper()
{
_sBasePath = Properties.Settings.Default.BasePath;
}
static string GetTempSavePath(string sUserId)
{
// dummy logic to compute return value, replace to taste
return Path.Combine(_sBasePath, sUserId.Substring(0, 4));
}
}
希望有意义
答案 1 :(得分:2)
问题在于您在派生类中重新声明静态变量。 DerivedClass中的MyNumber声明隐藏了基类中的声明。如果删除该声明,则派生类静态函数中对“MyNumber”的引用将引用基类变量。当然,如果删除声明,则无法在派生类中使用静态初始值设定项。
您可能需要考虑要求用户实例化ProfilePictures的实例,而不是为GetTempSavePath提供静态函数。这样,您可以覆盖GetTempSavePath方法以提供正确的TempPath。或者,您可以在派生类构造函数中设置静态路径值的值。
尽管可以将继承与静态成员一起使用,但如果没有“this”指针,则不能依赖于多态行为。
答案 2 :(得分:1)
静态成员不是虚拟成员,因此您无法覆盖它们。
当您致电DerivedClass.DoubleNumber
时,您实际上正在调用BaseClass.DoubleNumber
,因为DerivedClass
类没有该方法。此外,无论您如何调用该方法,该方法中MyNumber
的使用始终为BaseClass.MyNumber
。
您要查找的是可以在派生类中覆盖的虚拟属性。由于虚拟成员不能是静态成员,因此您需要使用该类的实例。如果保持对实例的引用是不切实际的,则可以使用单例模式。
答案 3 :(得分:1)
这种方式有效:
public class ClassA
{
protected static int num = 5;
public static int GetNum()
{
return num;
}
}
public class ClassB : ClassA
{
static ClassB()
{
num = 6;
}
}
但是,请注意在实例化一个对象之前和之后调用ClassB.GetNum()时的区别。静态初始化程序在您创建至少一个之前不会运行,因此如果没有创建任何内容,您将获得5,如果至少有一个对象,则为6。
答案 4 :(得分:0)
提供一个返回静态类的虚方法。
class BaseClass
{
public virtual int GetMyNumber() { return MyNumber; }
}
您可能想要使用虚拟财产......
答案 5 :(得分:0)
如果要封装整个对象的逻辑,也不建议使用过多的静态成员。例如,您的代码可以通过以下方式正确重写...这是oops中最推荐的,
class Program
{
static void Main(string[] args)
{
int Result = DerivedClass.Instance.DoubleNumber();
Console.WriteLine(Result.ToString()); // Returns 0
}
}
class BaseClass
{
protected BaseClass(){} // this enforces that it can not be created
public int MyNumber;
public virtual int DoubleNumber()
{
return (MyNumber*2);
}
}
public class DerivedClass : BaseClass
{
// this also ensures that it can not be created outside
protected DerivedClass(){
MyNumber = 5;
}
// only way to access this is by Instance member...
public static DerivedClass Instance = new DerivedClass();
}
这是我们访问.Net Library提供的配置值和许多其他单实例静态对象的方法。