将方法参数设置为只读

时间:2015-02-25 12:31:18

标签: c# .net parameters readonly

我如何创建一个方法,使对象成为只读目的

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对象不会改变它的值。

5 个答案:

答案 0 :(得分:5)

执行此操作的方法是通过getset访问者,只是不要定义集:

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#中的类是引用类型,因此如果Personclass,则无法执行您想要执行的操作。

您可以将其设为值类型(通过使其成为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
}