C# C语言中静态方法的模板#
我正在编写一个允许用户运行测试的应用程序。测试由许多不同的对象组成,例如配置、温度和基准。设置等在xml之间来回保存。我在代码中传递不同的元素,这样我就可以针对不同的情况以不同的方式构建最终的xml文档。我想这样做:C# C语言中静态方法的模板#,c#,inheritance,methods,static,C#,Inheritance,Methods,Static,我正在编写一个允许用户运行测试的应用程序。测试由许多不同的对象组成,例如配置、温度和基准。设置等在xml之间来回保存。我在代码中传递不同的元素,这样我就可以针对不同的情况以不同的方式构建最终的xml文档。我想这样做: public abstract class BaseClass<T> { abstract static XElement Save(List<T>); abstract static List<T> Load(XElement
public abstract class BaseClass<T>
{
abstract static XElement Save(List<T>);
abstract static List<T> Load(XElement structure);
}
public class Configuration : BaseClass<Configuration>
{
public string Property1 { get; set; }
public string Property2 { get; set; }
//etc...
public static XElement Save(List<Configuration>)
{
XElement xRoot = new XElement("Root");
//etc...
return xRoot;
}
public static List<Configuration> Load(XElement structure)
{
List<BaseClass> list = new List<BaseClass>();
//etc...
return list;
}
}
public class Temperature : BaseClass<Temperature>
{
public float Value { get; set; }
public static XElement Save(List<Temperature>)
{
//save
}
public static List<Temperature> Load(XElement structure)
{
//load
}
}
public static XElement Save(List<IBaseClass> list)
{
if (list is Temperature) {
// do temperature code
} else if (list is SomethingElse) {
// do something else
}
}
公共抽象类基类
{
抽象静态元素保存(列表);
抽象静态列表负载(XElement结构);
}
公共类配置:基类
{
公共字符串属性1{get;set;}
公共字符串属性2{get;set;}
//等等。。。
公共静态元素保存(列表)
{
XElement xRoot=新XElement(“根”);
//等等。。。
返回xRoot;
}
公共静态列表加载(XElement结构)
{
列表=新列表();
//等等。。。
退货清单;
}
}
公共类温度:基类
{
公共浮点值{get;set;}
公共静态元素保存(列表)
{
//拯救
}
公共静态列表加载(XElement结构)
{
//装载
}
}
[编辑]:修改问题(更改上述功能的签名)[/EDIT]
当然,我实际上不允许重写基类的静态方法。最好的方法是什么?我希望以下内容尽可能有效:
List<Temperature> mTemps = Temperature.Load(element);
List<Configuration> mConfigs = Configuration.Load(element);
Temperature.Save(mTemps);
Configuration.Save(mConfigs);
List mTemps=温度、负荷(元件);
List mConfigs=Configuration.Load(元素);
保存温度(mTemps);
配置保存(mConfigs);
[EDIT]更改了上面的预期用途代码[/EDIT]
我能想到的唯一解决办法是以下,这是不可接受的:
public class File
{
public static XElement Save(List<Temperature> temps)
{
//save temp.Value
}
public static XElement Save(List<Configuration> configs)
{
//save config.Property1
//save config.Property2
}
//etc...
}
公共类文件
{
公共静态元素保存(列表临时)
{
//保存温度值
}
公共静态元素保存(列表配置)
{
//保存config.Property1
//保存config.Property2
}
//等等。。。
}
如果你不在乎它的保存格式,你可以自由地使用序列化(在内部使用反射)
string SerialiseToString(T源)
{
使用(StringWriter sw=new StringWriter()&&XmlSerializer xml=new XmlSerializer(typeof(OrderedItem)))
{
序列化程序(软件,源代码);
返回sw.ToString();
}
}
如果您想将其合并到XML文件的更大部分中,最简单的方法是解析此输出并将其添加到您的XML文件中。或者,您可以自己反映属性。静态方法不是类实例的一部分。所以不管怎么说,覆盖它们没有任何意义。他们不能访问碰巧是其成员的实例的任何非静态部分 这是一种策略模式场景,例如,您可以只使用单个静态加载和保存方法来检查传递给它们的对象类型,并相应地执行操作。但这里有另一种稍微聪明一点的方法,它使用泛型类型创建原型并调用其方法,允许您将逻辑保留在每个派生对象类型中 (再次编辑) 这是另一条裂缝,与我最初的建议相同。实际上,我已经测试过了,而且效果很好,所以我认为这是获得您想要的所有功能的最好方法(除了测试类型和有条件地调用代码)。您仍然需要为
Load
传递一个类型,否则,运行时将不知道预期的返回类型。但是,Save
普遍有效。子类实现是强类型的
这只是使用列表中的第一个对象作为原型,非常简单
public interface IBaseObject
{
XmlElement Save(IEnumerable<IBaseObject> list);
IEnumerable<IBaseObject> Load(XmlElement element);
}
public interface IBaseObject<T> where T: IBaseObject
{
XmlElement Save(IEnumerable<T> list);
IEnumerable<T> Load(XmlElement element);
}
public class Temperature : IBaseObject<Temperature>, IBaseObject
{
public XmlElement Save(IEnumerable<Temperature> list)
{
throw new NotImplementedException("Save in Temperature was called");
}
public IEnumerable<Temperature> Load(XmlElement element)
{
throw new NotImplementedException("Load in Temperature was called");
}
// must implement the nongeneric interface explicitly as well
XmlElement IBaseObject.Save(IEnumerable<IBaseObject> list)
{
return Save((IEnumerable<Temperature>)list);
}
IEnumerable<IBaseObject> IBaseObject.Load(XmlElement element)
{
return Load(element);
}
}
// or whatever class you want your static methods living in
public class BaseObjectFile
{
public static XmlElement Save(IEnumerable<IBaseObject> list)
{
IBaseObject obj = list.DefaultIfEmpty(null).First(); // linq
return obj==null ? null : obj.Save(list);
}
public static IEnumerable<IBaseObject> Load<T>(XmlElement element)
where T: IBaseObject, new()
{
IBaseObject proto = new T();
return proto.Load(element);
}
}
公共接口IBaseObject
{
XmlElement保存(IEnumerable列表);
i可计算荷载(XmlElement);
}
公共接口IBaseObject,其中T:IBaseObject
{
XmlElement保存(IEnumerable列表);
i可计算荷载(XmlElement);
}
公共类温度:IBaseObject,IBaseObject
{
公共XmlElement保存(IEnumerable列表)
{
抛出新的NotImplementedException(“调用了保存温度”);
}
公共IEnumerable负载(XmlElement)
{
抛出新的NotImplementedException(“调用温度加载”);
}
//还必须显式地实现非通用接口
XmlElement IBaseObject.Save(IEnumerable列表)
{
返回保存((IEnumerable)列表);
}
IEnumerable IBaseObject.Load(XmlElement)
{
返回载荷(元件);
}
}
//或者任何你想要静态方法存在的类
公共类BaseObjectFile
{
公共静态XmlElement保存(IEnumerable列表)
{
IBaseObject obj=list.DefaultIfEmpty(null).First();//linq
返回obj==null?null:对象保存(列表);
}
公共静态IEnumerable负载(XmlElement)
其中T:IBaseObject,new()
{
IBaseObject proto=new T();
返回原型加载(元素);
}
}
(原始编辑)
这有一个问题,您必须使用类型调用静态方法,例如
BaseClass<Temperature>.Load()
BaseClass.Load()
对于Save方法,有一种方法可以解决这个问题,但是您想要的部分内容是不可能的。Load方法无法知道要返回的列表类型,因为它的唯一参数没有关于返回类型的信息。因此,它不可能决定创建哪种类型作为原型。所以不管怎样,如果您想使用公共加载方法,您必须向它传递一个类似于上述语法的类型
对于Save方法,您可以使用反射在静态方法中创建原型,方法是从第一个元素获取类型,然后从原型中调用Save方法。因此,如果您只需要使用Save方法,那么这是可能的
但最终,我认为这样做要简单得多:
public abstract class BaseClass<T>
{
abstract static XElement Save(List<T>);
abstract static List<T> Load(XElement structure);
}
public class Configuration : BaseClass<Configuration>
{
public string Property1 { get; set; }
public string Property2 { get; set; }
//etc...
public static XElement Save(List<Configuration>)
{
XElement xRoot = new XElement("Root");
//etc...
return xRoot;
}
public static List<Configuration> Load(XElement structure)
{
List<BaseClass> list = new List<BaseClass>();
//etc...
return list;
}
}
public class Temperature : BaseClass<Temperature>
{
public float Value { get; set; }
public static XElement Save(List<Temperature>)
{
//save
}
public static List<Temperature> Load(XElement structure)
{
//load
}
}
public static XElement Save(List<IBaseClass> list)
{
if (list is Temperature) {
// do temperature code
} else if (list is SomethingElse) {
// do something else
}
}
publicstaticxele