制作只读本地字符串C#

时间:2014-07-30 14:53:29

标签: c# .net string encapsulation protection

我有一个本地字符串(文件路径),我只需要从函数中检索一次,我想确保它永远不会再被修改。我不能使用const关键字,因为我的字符串的值是在运行时而不是编译时确定的。所以我尝试使用readonly关键字,但Visual Studio告诉我它对我的项目无效。我怎样才能达到我想要的保护水平,最好不要再做另一个课程?

为了简化和公司政策,我(大幅缩水)缩小并重命名我的课程和职能,但概念是相同的。

public class myClass
{
    private void myFunction()
    {
      readonly string filePath = HelperClass.getFilePath("123");

     //do stuff
    }
}

public static class HelperClass
{ 
    public static string getFilePath(string ID)
    {
        switch(ID)
        {
             case "123":
                 return "C:/123.txt";

             case "234":
                 return "C:/234.txt";

             default:
                 throw new Exception(ID + " is not supported");
        }
    }
}

===编辑PS2Goat ====

public class myClass
{
    protected SomeObject o;
    private virtual readonly string path;        

    public myClass(someObject o)
    {
        this.o = o;
        path = HelperClass.getFilePath(o.getID());
    }

    private virtual void myFunction()
    { 

     //do stuff
    }
}

public class myDerivedClass
{
    private override virtual readonly string path;        

    public myDerivedClass(someObject o) : base(o)
    {
        path = HelperClass.getFilePath(o.getID()); //ID will be different
    }

    private override void myFunction()
    { 

     //do different stuff
    }
}





public static class HelperClass
{ 
    public static string getFilePath(string ID)
    {
        switch(ID)
        {
             case "123":
                 return "C:/123.txt";

             case "234":
                 return "C:/234.txt";

             default:
                 throw new Exception(ID + " is not supported");
        }
    }
}

请注意,所以我遇到的问题是,如果我想抛出异常,我必须在父类中捕获它。 for constructor for this(直到支持该类),因为将在派生构造函数之前调用父构造函数。因此,在调用子构造函数(具有正确的ID)之前,将设置错误的ID。

5 个答案:

答案 0 :(得分:4)

您不能在方法中使用只读变量。因此,应将其提升为readonly static字段:

public class myClass
{
    private readonly static string filePath = HelperClass.getFilePath("123");
    private void myFunction()
    {    
      //do stuff
    }
}

这将导致您的filePath变量在首次访问myClass时被初始化。如果这不是您想要的,getFilePath是一个长时间运行/昂贵的操作,并且您希望等到myFunction被调用,您可以用System.Lazy<T>替换实现:

public class myClass
{
    private readonly static Lazy<string> filePath 
            = new Lazy<string>(() => HelperClass.getFilePath("123")));
    private void myFunction()
    {   
      string path = filePath.Value;
      //do stuff
    }
}

答案 1 :(得分:1)

readonly表示可以在类构造函数或instatiation中设置 ONLY 。所以,你可以把你的逻辑改成这样的东西:

public class myClass
{
    private readonly string _filePath;

    public myClass()
    {
        _filePath = HelperClass.getFilePath("123");
    }

    private void myFunction()
    {
      // Use your _filePath here...

     //do stuff
    }
}

public static class HelperClass
{ 
    public static string getFilePath(string ID)
    {
        switch(ID)
        {
             case "123":
                 return "C:/123.txt";

             case "234":
                 return "C:/234.txt";

             default:
                 throw new Exception(ID + " is not supported");
        }
    }
}

答案 2 :(得分:1)

您可以移动要在函数定义之外声明的readonly变量。

public class myClass
    {
        readonly string filePath = HelperClass.getFilePath("123");

        private void myFunction()
        {

         //do stuff with filePath
        }
    }

答案 3 :(得分:1)

由于这是变量而不是字段或属性,因此您无法将其标记为只读。但是你可以欺骗&#34;通过使用匿名类型实现您想要的,确保其属性是只读的。

例如:

    var data = new
    {
        FileName = HelperClass.getFilePath("123");
    };

答案 4 :(得分:0)

filePath变量提升为字段,应该修复错误。局部变量不能只读。

public class myClass
{
      readonly string filePath = HelperClass.getFilePath("123");
}