lar*_*ryq 12 c# setter properties internal
我正在试图找到一个很好的方法来解决这个问题.我有一个Customer类,它实现了ICustomer接口.该界面中包含许多属性:
public interface ICustomer
{
string FirstName {get; set;}
string LastName {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
我只希望某些类能够设置这些属性; 即项目中的那些课程.所以我考虑制作二传手internal:
public class Customer : ICustomer
{
string FirstName {get; internal set;}
string LastName {get; internal set;}
}
Run Code Online (Sandbox Code Playgroud)
我想将该setter标记为接口内部,因此不可能有人实现ICustomer,并且程序集之外的人修改这些属性.有没有办法做到这一点?
Ser*_*rvy 20
界面中的属性应该是只读的.即使接口中没有定义set接口,实现接口的具体类也可以接受.
public interface ICustomer
{
string FirstName { get; }
string LastName { get; }
}
public class Customer : ICustomer
{
public string FirstName { get; internal set; }
public string LastName { get; internal set; }
}
Run Code Online (Sandbox Code Playgroud)
如果通过接口公开setter非常重要,而不是让接口完全是只读的,那么你可以使用这样的东西:
public interface IReadCustomer
{
string FirstName { get; }
string LastName { get; }
}
internal interface IWriteCustomer
{
string FirstName { set; }
string LastName { set; }
}
internal interface IReadWriteCustomer : IReadCustomer, IWriteCustomer
{ }
public class Customer : IReadWriteCustomer
{
private string _firstName;
private string _lastName;
public string FirstName
{
get { return _firstName; }
internal set { _firstName = value; }
}
public string LastName
{
get { return _lastName; }
internal set { _lastName = value; }
}
string IReadCustomer.FirstName
{
get { return FirstName; }
}
string IReadCustomer.LastName
{
get { return LastName; }
}
string IWriteCustomer.FirstName
{
set { FirstName = value; }
}
string IWriteCustomer.LastName
{
set { LastName = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
我想将该setter标记为接口内部,因此不可能有人实现ICustomer,并且程序集之外的人修改这些属性.有没有办法做到这一点?
不幸的是,不幸的是,物业成员总是公开的.此外,在界面上指定部分属性的访问级别搞乱,IIRC.你可以做到这一点:
public interface ICustomer
{
string FirstName { get; }
string SecondName { get; }
}
internal interface ICustomerWithSetMethods : ICustomer
{
void SetFirstName(string name);
void SetLastName(string name);
}
public class Customer : ICustomerWithSetMethods
Run Code Online (Sandbox Code Playgroud)
然后从外部看起来它Customer只是实现ICustomer,但从代码内部将看到它实现ICustomerWithSetMethods.
不幸的是,如果你的API需要声明任何公共方法,而你真的只想声明一个返回类型ICustomer,那么它就不能很好地发挥作用,但实际上你知道它总是如此ICustomerWithSetMethods.
假设您仍然希望允许多个实现,您可能会改为使用抽象类:
public abstract class CustomerBase
{
public abstract string FirstName { get; }
public abstract string LastName { get; }
internal abstract void SetFirstName(string name);
internal abstract void SetLastName(string name);
}
Run Code Online (Sandbox Code Playgroud)
现在我们有一点点奇怪的是,程序集之外没有人可以扩展你的CustomerBase,因为有些抽象方法他们不得不覆盖它们甚至看不到 - 但它确实意味着你可以CustomerBase在你的API中使用.
这是我们最终在Noda Time中为日历系统采用的方法 - 当我第一次提出计划时,我在博客上写了这篇文章.我通常更喜欢接口来抽象类,但这里的好处是显着的.
| 归档时间: |
|
| 查看次数: |
10553 次 |
| 最近记录: |