我如何创建一个方法,使对象成为只读目的
public class Person
{
public string Name;
}
public void RunMe(Person p)
{
p.Name="XXXX";
}
var p =new Person();
p.Name="YYYY";
RunMe(p);
Console.WriteLine(p.Name);
我收到了XXXX。但我希望person对象不会改变它的值。
答案 0 :(得分:5)
执行此操作的方法是通过get
和set
访问者,只是不要定义集:
public String Name { get; }
这将使您可以像处理普通字段一样处理的属性。使用方法来设置支持字段,您可以在msdn
上阅读下面的属性更复杂一些如果您需要只能设置一次属性,那么将set
定义为private并将参数传递给构造函数:
public class Person
{
public Person(String name)
{
this.Name = name;
}
public String Name { get; private set; }
}
答案 1 :(得分:5)
您可以使用接口来限制访问。最好将接口而不是具体对象作为参数传递给方法。
public interface IReadablePerson
{
string Name { get; }
}
public interface IWritablePerson
{
string Name { set; }
}
public class Person : IReadablePerson, IWritablePerson
{
public string Name { get; set; }
}
然后有一个像这样的方法
public void RunMe(IReadablePerson p)
{
p.Name = "XXXX"; //compile time error!!!
}
答案 2 :(得分:1)
C#中的类是引用类型,因此如果Person
是class
,则无法执行您想要执行的操作。
您可以将其设为值类型(通过使其成为struct
)在这种情况下,将传入对象的副本,但这可能会影响程序中的其他某些点,因此警惕,如果你这样做。
答案 3 :(得分:1)
似乎你想以某种方式锁定会员。一种选择是制作"设置"依赖于这样的另一个成员:
public class Name
{
public bool Locked { get; set; }
private string name;
public string Name
{
get { return this.name; }
set
{
if(!this.Locked)
this.name = val;
}
}
}
编辑:使锁永久化的替代方法。
public class Person
{
private bool locked = false;
public void Lock()
{
this.locked = true;
}
public bool Locked
{
get { return this.locked; }
}
// add same Name member as above
}
编辑:还有另一种使用密钥锁定的方法。
private object key = null;
public bool Locked
{ get { return this.key != null; } }
public void Lock(object obj)
{
if (this.key == null)
{
this.key = obj;
}
}
public void Unlock(object obj)
{
if (this.key == obj)
{
this.key = null;
}
}
如果您想尝试使用错误的密钥对象解锁,则可以抛出异常。
答案 4 :(得分:1)
首次设置属性后描述的行为是:
private string _name;
public string Name
{
get { return _name; }
set { // no setting }
}
这不是一个好的做法。 您为属性创建意外行为(如果这是一个公共类)。 任何消耗程序集都无法查看get和set方法的主体,期望set方法能够以某种方式运行(设置一个值)。
这种行为应该采用单独的方法。 通过这种方式,您可以查看是否已更改,如果需要则抛出异常,如果更改则返回true。 然后,您仍然可以使用该属性来获取值。
private bool _locked;
public string Name { get; private set;}
public boolSetName(string value)
{
bool hasChanged = false;
if(!_locked)
{
Name = value;
_locked = true;
hasChanged = true;
}
return hasChanged
}