C# 设置在具体类的接口中定义的只读属性
我有一个只读属性的接口C# 设置在具体类的接口中定义的只读属性,c#,inheritance,properties,interface,C#,Inheritance,Properties,Interface,我有一个只读属性的接口 public interface IPerson { string Name { get; } } 和一个具体的类 public class Person : IPerson { public Person() { Name = "Person"; } public string Name { get { return Name;
public interface IPerson
{
string Name { get; }
}
和一个具体的类
public class Person : IPerson
{
public Person()
{
Name = "Person";
}
public string Name
{
get
{
return Name;
}
}
}
我希望名称只能在这个类的外部读取,但如何在具体类中设置它呢
错误:无法为人员分配名称
如何在Person类中设置此属性的值?您可以使用私有属性来保存该值
public class Person : IPerson
{
private string _name;
public Person()
{
_name = "Person";
}
public string Name
{
get
{
return _name;
}
}
}
这与接口无关,只是错误地声明了属性。在C#6中,可以创建如下只读属性:
public class Person : IPerson
{
public Person()
{
Name = "Person";
}
public string Name { get; }
}
在早期版本中,您可以使用只读备份字段,可以设置:
public class Person : IPerson
{
private readonly string _name;
public Person()
{
_name = "Person";
}
public string Name
{
get { return _name; }
}
}
注意,接口只需要属性有一个getter,实现不必是只读的。如果有理由修改该值,则可以添加setter:
public class Person : IPerson
{
public Person()
{
Name = "Person";
}
public string Name { get; set; }
}
如果您只需要在类中更改值,则setter可以是私有的。尝试使用:
然后,您可以在任何方法或构造函数中设置
\u name
的值。现在,您正试图通过读取属性来读取属性。不用说,这将导致一个无休止的循环。相反,您需要使用完整的自动属性,或者手动备份字段
public class Person : IPerson
{
public Person()
{
Name = "Person";
}
public string Name { get; private set; }
}
您只需拥有一个私人setter(c#6之前): 我希望名称只能在这个类的外部读取,但是如何在具体类中设置它呢 首先,让我们认识到:一个接口只描述一组
公共
需求;它不会阻止我们实现其他公共成员,也不会限制我们创建私有成员的能力
因此,要使属性从类内部可写但在其他地方为只读,我们可以使用private
范围声明set
方法:
public class Person : IPerson
{
// Name is read-only outside the class, but can be set internally
public string Name { get; private set; } = "DefaultName";
public Person() { }
public Person(string name)
{
// Potentially do some validation before setting the name
if (!IsValidName(name))
throw new ArgumentException("Name cannot be null, empty, or whitespace.");
Name = name;
}
private bool IsValidName(string name)
{
return !string.IsNullOrWhitespace(name);
}
// Continued below...
如果我们愿意,我们可以通过一个方法来访问私有setter。这样做通常是为了使一个人的重命名非常有目的(例如,当打算进行比较时,它可以防止意外的赋值)。如果客户端尝试person.Name=“Foo”,则会从编译器中获得设计时错误但是他们可以写person.RenameAs(“Foo”)代码>
但是,这仅在属性确实应该是只读的情况下才起作用。OP的描述中不清楚他是否想稍后在Person
类中更改值。谢谢-我现在明白了这是怎么回事。我不需要在编写后更改名称(在本例中),但如果我更改了,那么我将使用accessors。我现在意识到,我可以简单地排除返回名称;咬了一口,就得到了;
public class Person : IPerson
{
public Person()
{
Name = "Person";
}
public string Name { get; private set; }
}
public class Person : IPerson
{
// Name is read-only outside the class, but can be set internally
public string Name { get; private set; } = "DefaultName";
public Person() { }
public Person(string name)
{
// Potentially do some validation before setting the name
if (!IsValidName(name))
throw new ArgumentException("Name cannot be null, empty, or whitespace.");
Name = name;
}
private bool IsValidName(string name)
{
return !string.IsNullOrWhitespace(name);
}
// Continued below...
public void RenameAs(string newName)
{
// Potentially do some validation before setting the name
if (IsValidName(newName)) Name = newName;
}
}