扩展方法不规则行为

本文关键字:不规则 方法 扩展 | 更新日期: 2023-09-27 17:50:41

考虑以下内容:

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 总是空。

知道为什么吗?

扩展方法不规则行为

你本质上是在试图改变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);
        }
    }
}

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

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

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

我用了这种难看的方法:

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

所以你可以叫它

MyType myObject = filename.LoadFromFile<MyType>(true);
但是最大的缺点是这个扩展函数现在将为每个字符串提供。