我有一个.Net C#类,我需要将变量设为public。我需要在方法中初始化此变量(不在构造函数中)。但是,我不希望变量可由其他类修改。这可能吗?
答案 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)
将其定义为私有?这就是你要求的,你可以在容器类里面的任何地方修改它,但是你不能把它放在一边