我该如何创建一个具有只读对象参数的方法?
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"
上述代码导致人名为"XXXX"。我想防止
RunMe
方法改变人的属性。我该如何创建一个具有只读对象参数的方法?
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"
RunMe
方法改变人的属性。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!!!
}
get
和set
访问器完成,只需不定义set
即可。public String Name { get; }
set
定义为私有,并将参数传递到构造函数中:public class Person
{
public Person(String name)
{
this.Name = name;
}
public String Name { get; private set; }
}
p.name="YYYY";
,因为他期望能够这样做。如果我理解问题的意思,他想要一个方法(不在类中)不改变传入的原始对象,而不是在所有地方保护属性或字段。 - Jcl看起来你希望能够锁定成员。一种选择是将“set”操作与另一个成员相关联,就像这样:
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;
}
}
obj
,您想要操作它,将其作为只读传递给方法,然后再次操作它。您该如何实现? - Hamid Pourjamprivate string _name;
public string Name
{
get { return _name; }
set { // no setting }
}
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
}
p.Name="YYYY";
来更改名称。这将不会在任何地方更改它,并且它将不会打印任何内容(而不是在调用“RunMe”方法之前分配给它的名称)。 - Jclp.Name="YYYY"
部分犯了错误。 - Jasper SaaltinkC#中的类是引用类型,所以如果Person
是一个class
,那么没有办法做你想做的事情。
你可以将其作为值类型(通过使其成为struct
)来实现,在这种情况下,将传递对象的副本,但这可能会在程序的其他点产生影响,所以如果你这样做要小心。