扩展方法不规则行为

时间:2011-04-21 13:57:32

标签: c# extension-methods

请考虑以下事项:

public static class FileSerializer
{
    public static void SaveToFile<T>(this T obj, String fileName)
    {
        String dbFile = Path.Combine(Application.StartupPath, fileName);

        using (Stream stream = File.Open(dbFile, FileMode.Create))
        {
            BinaryFormatter bFormatter = new BinaryFormatter();
            lock (obj) bFormatter.Serialize(stream, obj);
        }
    }

    public static void LoadFromFile<T>(this T obj, String fileName, Boolean ensureExists)
    {
        String dbFile = Path.Combine(Application.StartupPath, fileName);

        if (!File.Exists(dbFile))
            if (ensureExists)
                throw new FileNotFoundException("File not Found!");
            else return;

        using (Stream stream = File.Open(dbFile, FileMode.Open))
        {
            if (stream.Length > 0)
            {
                BinaryFormatter bFormatter = new BinaryFormatter();
                obj = (T)bFormatter.Deserialize(stream);
            }
        }
    }
}

即使我附上调试器,并且上面代码的最后一行中的obj也有记录,当我使用这样的方法时:

lstServers.LoadFromFile("Servers.dat", false);

lstServers 始终为空。

任何想法为什么?

3 个答案:

答案 0 :(得分:2)

您实际上是在尝试更改obj的引用,而这种引用无法以这种方式完成。你得到的最好的是它的非扩展版本:

public static T LoadFromFile<T>(String fileName, Boolean ensureExists)
{
    String dbFile = Path.Combine(Application.StartupPath, fileName);

    if (!File.Exists(dbFile))
        if (ensureExists)
            throw new FileNotFoundException("File not Found!");
        else return default(T);

    using (Stream stream = File.Open(dbFile, FileMode.Open))
    {
        if (stream.Length > 0)
        {
            BinaryFormatter bFormatter = new BinaryFormatter();
            return (T)bFormatter.Deserialize(stream);
        }
    }
}

答案 1 :(得分:1)

LoadFromFile不应该是一个扩展方法,只是一个返回其结果的普通静态方法:

lstServers = FileSerializer.LoadFromFile("Servers.dat", false);

问题是您分配给实例参数,这对传递给方法外部的该参数的变量没有任何影响。您不能通过引用(refout)在扩展方法中的实例参数中使用,这是使代码工作所需的。

答案 2 :(得分:-1)

我用这种丑陋的方式做到了这一点:

public static T LoadFromFile<T>(this String fileName, Boolean ensureExists);

所以你可以称之为

MyType myObject = filename.LoadFromFile<MyType>(true);

但最大的缺点是现在将为每个字符串提供此扩展功能。