get {}未按预期工作

时间:2011-12-09 16:23:23

标签: c# .net

  public class Settings
    {
        public static readonly string fileName = "config.ini";
        private IConfigSource src
        {
            get
            {
                CreateIfNotExists();
                return new IniConfigSource(fileName);
            }
        }

       public void test1()
        {
            //var src = new IniConfigSource(fileName); ;
            src.Configs["DATA"].Set("baa", "haaaaee");
            src.Save();
        }

       public void test2()
        {
            var src2 = new IniConfigSource(fileName); ;
            src2.Configs["DATA"].Set("baa", "haaaaee");
            src2.Save();
        }

    public Stream CreateIfNotExists()
    {
        if (!File.Exists(fileName))
        {
            Stream file = File.Create(fileName);
            return file;
        }

        return null;
    }
}

为什么test2()方法正常,test1()不起作用?

4 个答案:

答案 0 :(得分:2)

它不起作用,因为你的“src”属性每次调用都会创建一个新的IniConfigSource。您的“测试”期望它与呼叫相同。

将IniConfigSource的结果存储在私有变量中,如果设置了则使用它。

    private IConfigSource _src;
    private IConfigSource src
    {
        get
        {
            if( _src == null )
                _src = new IniConfigSource(fileName);
            return _src;
        }
    }

我不打算理解为什么CreateIfNotExists完全存在,考虑到返回的Stream从未使用过并被丢弃到GC。

答案 1 :(得分:2)

问题是您正在使用两个src实例。将您的代码更改为:

public class Settings     
{ 
     public static readonly string fileName = "config.ini"; 
     private IConfigSource src;
     private IConfigSource Src
     {  
         get  
         { 
              CreateIfNotExists();  
              return src; 
         }  
     }    
     public void test1()   
     {
         //var src = new IniConfigSource(fileName); 
         Src.Configs["DATA"].Set("baa", "haaaaee");      
         Src.Save();     
     }      
     public void test2()  
     { 
         Src.Configs["DATA"].Set("baa", "haaaaee");
         Src.Save();         
     }    
     public Stream CreateIfNotExists()     
     { 
         if (!File.Exists(fileName))         
         {
              Stream file = File.Create(fileName);
              src = new IniConfigSource(fileName);
              return file;        
         } 
         src = null;
         return null;    
      }
  } 

答案 2 :(得分:1)

srctest1中的

test2IniConfigSource的两个不同实例(不再适用于您的修改)。

test1失败的原因是每一行都创建了一个新实例。

// src property creates new IniConfigSource and sets value appropriately
src.Configs["DATA"].Set("baa", "haaaaee"); 

// src property creates new IniConfigSource and essentially saves nothing
src.Save();

答案 3 :(得分:0)

CreateIfNotExists创建FileStream的实例,但不会将其丢弃。这导致FileStream锁定文件,因此后续打开该文件失败。

第一次测试中的IniConfigSource实例也可能会使文件保持打开状态,但我不确定,因为您没有发布相关的源代码。

您的延迟初始化模式也会中断,每次访问都会返回IniConfigSource的新实例。如果你想要延迟初始化,为什么不使用Lazy<T>类?


除了这个bug之外,带有副作用的getter是非常坏的样式。

另一个(次要)问题是存在检查和调用创建之间的竞争条件。如果文件在代码之间被删除则失败。