我有一个基类和派生类,如下所示:
public abstract class MyBase
{
protected string _data;
protected string GetData_Internal() {return _data;}
protected abstract void SetData(string data);
}
public class MyDerived : MyBase
{
protected override void SetData(string data) {_data = "my data";}
public static string GetData()
{
var instance = new MyDerived();
return instance.GetData_Internal();
}
}
此类的所需用法如下:
string data1 = MyDerived.GetData();
string data2 = MyDerived2.GetData(); // another class dervied from MyBase
我不能使这些类保持静态,因为静态类和派生类不能很好地协同工作。所以我将函数GetData()
设为静态,这允许我像我想要的那样使用类。
除了MyDerived
中设置的数据值之外,我将有多个与SetData()
完全相同的类。
我想将GetData()
移出派生类并进入基类,这样我就不会在每个派生类中复制该代码。
我无法弄清楚如何做到这一点,因为基类中的静态方法不知道要新建什么类型的对象。
那么,有没有办法做我想做的事情,保持与班级的静态互动,同时避免代码重复以实现它?
答案 0 :(得分:4)
如果您正在处理静态数据,那么您可能需要的是仅能实例化一次的单例对象。它们具有支持继承和接口实现以及静态访问的优点。此外,与静态类不同,它们可以作为参数传递给方法并存储在字段,属性和变量中。
您可以使用属性而不是getter和setter方法。这简化了您的基类:
public abstract class MyBase
{
public string Data { get; set; }
}
您可以像这样实施singleton pattern:
public class MyDerived : MyBase
{
#region Singleton Pattern
public static readonly MyDerived Instance = new MyDerived();
private MyDerived()
{
}
#endregion
}
创建一个公共静态只读字段,该字段返回该类的唯一实例,并使构造函数为私有,以便禁止在类本身之外创建实例。如果需要,构造函数还可以初始化Data
的值。
你可以像这样使用单身人士:
MyDerived.Instance.Data = "my data";
string data = MyDerived.Instance.Data;
MyDerived2.Instance.Data = "my data 2";
...
另请参阅:Implementing Singleton in C#了解实现单例模式的各种方法。
答案 1 :(得分:0)
首先,我不完全确定你想要完成的是什么。所以,我没有评论这是否是一个好主意。您可以获得行为,其行为有点类似于具有静态的基类上的重写方法。相反,你覆盖基地然后调用它。我做类似的事情来从类中获取实例或实例集合:
public class Dog
{
public static Dog GetById(int dogId)
{
//Return dog
}
}
public class Lab : Dog
{
public new static Lab GetById(int dogId)
{
//Return same dog, as a lab
}
}
快速而可怕,但希望有用的版本可能会像下面这样开始。如果我能更好地理解你的意图,我或许可以把它变成实用的东西。
public abstract class MyBase
{
public static string GetData()
{
return "BASE STUFF";
}
}
public class MyDerivedA : MyBase
{
protected const string MySpecialData = "AAAAAA";
public new static string GetData()
{
return MyBase.GetData() + MySpecialData;
}
}
public class MyDerivedB : MyBase
{
protected const string MySpecialData = "BBBBBBB";
public new static string GetData()
{
return MyBase.GetData() + MySpecialData;
}
}