C#公共变量在类中可写,但在类外只读

时间:2011-01-11 20:19:12

标签: c# variables public

我有一个.Net C#类,我需要将变量设为public。我需要在方法中初始化此变量(不在构造函数中)。但是,我不希望变量可由其他类修改。这可能吗?

9 个答案:

答案 0 :(得分:67)

不要使用字段 - 使用属性:

class Foo
{
    public string Bar { get; private set; }
}

在此示例中,Foo.Bar在任何地方都可读,只能由Foo本身的成员写入。

作为旁注,此示例使用版本3中引入的C#功能,称为自动实现的属性。这是语法糖,编译器将转换为具有私有支持字段的常规属性,如下所示:

class Foo
{
    [CompilerGenerated]
    private string <Bar>k__BackingField;

    public string Bar
    {
        [CompilerGenerated]
        get
        {
            return this.<Bar>k__BackingField;
        }
        [CompilerGenerated]
        private set
        {
            this.<Bar>k__BackingField = value;
        }
    }
}

答案 1 :(得分:11)

public class Foo
{
  public string Bar { get; private set; } 
}

答案 2 :(得分:6)

你必须使用一个属性。如果您对自动getter / setter实现没问题,这将有效:

public string SomeProperty { get; private set; }

请注意,除非在某些有限的情况下,否则不应将字段公开为公开字段。改为使用属性。

答案 3 :(得分:4)

不确定。将它设为属性,并将setter设为私有:

public Int32 SomeVariable { get; private set; }

然后设置它(从类中的某个方法中):

SomeVariable = 5;

答案 4 :(得分:3)

使用私有变量并公开公共属性。

class Person
{
  private string name;

  public string Name
  {
    get
    {
      return name;
    }
  }
}

答案 5 :(得分:2)

您是否不允许使用房产?如果你是:

private string _variable
public string Variable {
    get {
        return _variable;
    }
}

答案 6 :(得分:1)

Necro肯定,但是这提到了6.0中语言的改进

class Foo {

    // The new assignment constructor is wonderful shorthand ensuring
    // that the var is only writable inside the obj's constructor
    public string Bar { get; } = String.Empty;

    }

答案 7 :(得分:1)

只要您不使用引用类型,到目前为止的答案仍然有效。否则,您仍然可以操纵该变量的内部。 e.g:

using System;
namespace Playground
{
    class Program
    {
        static void Main(string[] args)
        {
            var fo = new Fo();
            fo.Init();
            Console.WriteLine(fo.SomeBar.SomeValue);
            fo.SomeBar.SomeValue = "Changed it!";
            Console.WriteLine(fo.SomeBar.SomeValue);
            Console.Read();
        }
        public class Fo
        {
            public Bar SomeBar { get; private set; }
            public void Init()
            {
                SomeBar = new Bar{SomeValue = "Hello World!"};
            }
        }
        public class Bar
        {
            public String SomeValue { get; set; }
        }
    }
}
这将导致控制台输出:

Hello World!
Changed it!

这可能正是您想要的,因为您无法更改 SomeBar ,但如果您想使变量的内部不可修改,则需要传回变量的副本,例如:


using System;
namespace Playground
{
    class Program
    {
        static void Main(string[] args)
        {
            var fo = new Fo();
            fo.Init();
            Console.WriteLine(fo.SomeBar.SomeValue);
            fo.SomeBar.SomeValue = "Changed it!";
            Console.WriteLine(fo.SomeBar.SomeValue);
            Console.Read();
        }
        public class Fo
        {
            private Bar _someHiddenBar;
            public Bar SomeBar => new Bar(_someHiddenBar);
            public void Init()
            {
                _someHiddenBar = new Bar{SomeValue = "Hello World!"};
            }
        }
        public class Bar
        {
            public String SomeValue { get; set; }
            public Bar(){}
            public Bar(Bar previousBar)
            {
                SomeValue = previousBar.SomeValue;
            }
        }
    }
}
 这将导致输出:

Hello World!
Hello World!

请参阅评论,了解我添加第三个示例的原因:


using System;
namespace Playground
{
    class Program
    {
        static void Main(string[] args)
        {
            var fo = new Fo();
            fo.Init();
            Console.WriteLine(fo.SomeBar.SomeValue);
            //compile error
            fo.SomeBar.SomeValue = "Changed it!";
            Console.WriteLine(fo.SomeBar.SomeValue);
            Console.Read();
        }
        public class Fo
        {
            private Bar _someHiddenBar;
            public Bar SomeBar => new Bar(_someHiddenBar);
            public void Init()
            {
                _someHiddenBar = new Bar("Hello World!");
            }
        }
        public class Bar
        {
            public String SomeValue { get; }
            public Bar(string someValue)
            {
                SomeValue = someValue;
            }
            public Bar(Bar previousBar)
            {
                SomeValue = previousBar.SomeValue;
            }
        }
    }
}

答案 8 :(得分:-1)

将其定义为私有?这就是你要求的,你可以在容器类里面的任何地方修改它,但是你不能把它放在一边