定义静态扩展方法的替代方法

发布于 2024-08-22 22:46:52 字数 1032 浏览 8 评论 0原文

我知道我无法在 C# 中扩展静态类,我并不真正理解原因,但我确实知道这是不可能的。

因此,考虑到这一点,这就是我想要实现的目标:

public static class GenericXmlSerialisationExtender
{
    public static void WriteToXML<T>(this T targetObject, string fileName)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        using (TextWriter writer = new StreamWriter(fileName, false, Encoding.UTF8))
        {
            serializer.Serialize(writer, targetObject);
        }
    }

    public static T ReadFromXML<T>(string fileName)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        using (TextReader reader = new StreamReader(fileName, Encoding.UTF8))
        {
            return (T)serializer.Deserialize(reader);
        }
    }
}

即我想为实例定义 .WriteToXML (有很多我需要使用的配置/静态数据类,它们只使用普通的 XML 序列化),并且然后 .ReadFromXML 类型。

因此,我可以有效地调用类似的内容:

MyType typeInstance = MyType.ReadFromXML(path_to_data);

封装它的“正确”方式是什么?我曾经和一位同事共事,他认为“代码重用”就是复制和复制。粘贴,我不想把自己放在那个括号里!

I understand that I can't extend static classes in C#, I don't really understand the reason why, but I do understand that it can't be done.

So, with that in mind, here is what I wanted to achieve:

public static class GenericXmlSerialisationExtender
{
    public static void WriteToXML<T>(this T targetObject, string fileName)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        using (TextWriter writer = new StreamWriter(fileName, false, Encoding.UTF8))
        {
            serializer.Serialize(writer, targetObject);
        }
    }

    public static T ReadFromXML<T>(string fileName)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        using (TextReader reader = new StreamReader(fileName, Encoding.UTF8))
        {
            return (T)serializer.Deserialize(reader);
        }
    }
}

I.e. I wanted to define .WriteToXML for instances (there are quite a lot of config / static data classes which I need to use which just use vanilla XML Serialization), and then .ReadFromXML for types.

So effectively I could call something like:

MyType typeInstance = MyType.ReadFromXML(path_to_data);

What would be the 'proper' way of encapsulating that? I once worked with a colleague who believed 'code re-use' was copy & paste, and I'd rather not put myself in that bracket!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

任性一次 2024-08-29 22:46:52

您可以按照已经完成的方式定义它,但要调用它,您将使用标准静态方法调用:(

MyClass deserializedObject = GenericXmlSerialisationExtender.ReadFromXML<MyClass>(@"c:\filename.xml");

如果您这样做,您可能希望为 GenericXmlSerializationExtender 类提供更合适的名称,或者将其移动到不同的位置静态类)


扩展方法不能在静态方法上工作的原因是没有对象来附加扩展方法。

在您的示例中:

public static T ReadFromXML<T>(string fileName)

该行中没有任何地方定义您想要扩展的类型。扩展方法要求第一个参数是您希望扩展方法对其执行操作的对象。

扩展方法只是语法糖,是创建静态辅助方法的好方法。

在 .net 2.0 中,您可以这样写:

public static class StringHelper
{
    public static String AddFullStop(String data)
    {
        return data + ".";
    }
}

String input = "test";
String output = StringHelper.AddFullStop(input);

.net 3.5 使您能够执行此操作:

public static class StringExtensions
{
    public static String AddFullStop(this String data)
    {
        return data + ".";
    }
}

String input = "test";
String output = input.AddFullStop();

因此,当您想要在方便的扩展方法范围之外执行某些操作时,您只需回退到较旧的静态辅助方法模式即可。

You would define it in exactly the way you have done already, but to call it you would use a standard static method call:

MyClass deserializedObject = GenericXmlSerialisationExtender.ReadFromXML<MyClass>(@"c:\filename.xml");

(You might want to give your GenericXmlSerialisationExtender class a more appropriate name if you do this, or move it to a different static class)


The reason that extension methods can't work on Static methods, is that there is no object to attach the extension method too.

In your example:

public static T ReadFromXML<T>(string fileName)

Nowhere in that line have you defined the type that you would like to extend. Extension methods require that the first parameter be an object that you would like the extension method to act upon.

Extension methods are just syntactic sugar, as a nice way of creating a static helper method.

in .net 2.0 you would write:

public static class StringHelper
{
    public static String AddFullStop(String data)
    {
        return data + ".";
    }
}

String input = "test";
String output = StringHelper.AddFullStop(input);

.net 3.5 gives you the ability to do this:

public static class StringExtensions
{
    public static String AddFullStop(this String data)
    {
        return data + ".";
    }
}

String input = "test";
String output = input.AddFullStop();

So when you want to do something outside the scope of the handy extension methods, you just fall back to the older static helper method pattern.

迎风吟唱 2024-08-29 22:46:52

我实际上并不是在推荐这个,而是作为一种选项:用

public static T ReadFromXML<T>(this T ignored, string fileName)
{
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    using (TextReader reader = new StreamReader(fileName, Encoding.UTF8))
    {
        return (T)serializer.Deserialize(reader);
    }
}

以下方式调用它:

MyType typeInstance = default(MyType).ReadFromXml(path_to_data);

这非常可怕,但在某种程度上它是解决问题的一种方法。

我怀疑我实际上只是忍气吞声并做:

MyType typeInstance = GenericXmlSerialisationExtender.ReadFromXml<MyType>(...);

如果您可以给GenericXmlSerializationExtender一个更活泼的名称,那应该不会太痛苦。

I'm not actually recommending this, but as an option:

public static T ReadFromXML<T>(this T ignored, string fileName)
{
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    using (TextReader reader = new StreamReader(fileName, Encoding.UTF8))
    {
        return (T)serializer.Deserialize(reader);
    }
}

Call it with:

MyType typeInstance = default(MyType).ReadFromXml(path_to_data);

It's pretty horrible, but it's one way round the problem to some extent.

I suspect I'd actually just suck it up and do:

MyType typeInstance = GenericXmlSerialisationExtender.ReadFromXml<MyType>(...);

If you can give GenericXmlSerialisationExtender a snappier name, that shouldn't be too painful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文