解释
我有一个像这样的抽象类:
public abstract class Serializer<T> where T : new()
{
T obj { get; set; }
public string ToXML()
{
// return string XML
}
}
另一个继承此抽象类的类:
public class Account : Serializer<Account>
{
// Code
// I don't want to have to implement the methods of
// the inherited class/interface.
}
我想像这样访问它:
Account account = new Account();
Console.WriteLine(account.ToXML());
问题:
我是否可以执行此操作并将account
传递给属性obj
,以便ToXML
可以执行将对象转换为字符串的任务?
Serializer s = new Serializer();
s.ToXML(account);
我更愿意让每个对象继承Serialize
类及其所有方法,并且只是能够知道除了添加类的继承而不进行任何编辑,我现在可以访问这些方法。< / p>
另一方面,我觉得继承一个类在选择一个接口或一个类之间违反了 is-a 和 can-do 原则,但我不这样做想要覆盖所有的方法,当我已经编写了一般编写的代码时(即,我不想实现接口)。有没有办法像类一样继承接口的方法(没有实现/重写)。
答案 0 :(得分:2)
尝试返回this
:
T obj { get { return (T)this; } }
但是,这意味着子类必须将自己作为一个类型参数提供,它是一种奇怪的反复出现的“模板”模式......但是,您可能不一定需要知道对象的类型。编译时将其序列化为XML(如果使用常用的序列化程序),因此在序列化程序方法中访问this
就可以了,不需要那个类型参数和该属性。
我个人更喜欢更多hands off approach到抽象基类(使用XmlSerializer
):
public interface MXmlSerializable { }
public static class XmlSerializable {
public static string ToXml(this MXmlSerializable self) {
if (self == null) throw new ArgumentNullException();
var serializer = new XmlSerializer(self.GetType());
using (var writer = new StringWriter()) {
serializer.Serialize(writer, self);
return writer.GetStringBuilder().ToString();
}
}
}
M
代表 mixin 。它实际上是一个带扩展方法的标记接口。像这样使用它:
public class Account : MXmlSerializable {
...
}
...
Account account = new Account();
...
string accountXml = account.ToXml();
答案 1 :(得分:0)
这样做是怎么回事;
public string ToXML()
{
convert `this` to xml directly
// return string XML
}
为什么需要该属性返回对类本身的引用。
使用上述结构,您可以执行以下操作,甚至不需要T
属性
Account account = new Account();
Console.WriteLine(account.ToXML());
答案 2 :(得分:0)
你的构造几乎没有意义。 Serializer<T>
实例没有明确的观点指向自己。您可以轻松使用this
并将其投射到T
。此外,除非您的ToXML
方法实现了一些非常通用的XML序列化算法(比如通过反射处理当前实例),否则您应该将其设为virtual
并将特定实现放在Serializer<T>
的祖先中
另外,我还会反对你的继承方法。如果您的Account
类实际上是单一目的帐户序列化程序,那么请将其命名为AccountSerializer
)。如果没有,并且Account
表示实际帐户,则是,从独立读者的角度来看,您混合了两个主要概念:业务对象(Account
)和一些技术机制({{1} })。
如果您有通用序列化算法,为什么不在Serializer<T>
中接受Serializer<T>
个单独的非T
类?最终你会更好地分离关注点。
有没有办法像类一样继承接口的方法(没有实现/覆盖)。
没有。接口是接口,而不是嵌入特定代码的类。
答案 3 :(得分:0)
如果Abstract类中的代码不会改变只是序列化对象,这种方法没有意义,序列化你不需要知道对象类型(特别是如果你使用xml这意味着构建一个易于访问的字符串)。
如果您希望序列化仅适用于某些对象,请创建一个接口,即
public interface ISerialize
{
}
public class Account : ISerialize
{
}
然后创建一个Extension方法
public static class ExtenstionMethods
{
public static string ToXml(this ISerialize obj)
{
// code to build xml string
}
}
这样你可以做你想做的事情,因为Account是Interface的,而ExtensionMethods只能在那个接口上工作,所以你只需要ExtensionMethods类中的代码然后在任何你想要使用的地方包含命名空间“ToXml()”等
Account account = new Account();
Console.WriteLine(account.ToXML());