Oop 纯写属性有实际应用吗?
我不知道为什么我开始考虑这个,但现在我似乎无法停止 在C#-可能还有很多其他语言中,我记得Delphi也允许您这样做-编写以下语法是合法的:Oop 纯写属性有实际应用吗?,oop,properties,language-agnostic,Oop,Properties,Language Agnostic,我不知道为什么我开始考虑这个,但现在我似乎无法停止 在C#-可能还有很多其他语言中,我记得Delphi也允许您这样做-编写以下语法是合法的: 类怪人类 { 私有void Hello(字符串名称) { WriteLine(“你好,{0}!”,name); } 公共字符串名 { 集合{Hello(name);} } } 换句话说,该属性有一个setter,但没有getter,它是只写的 我想我想不出为什么这是非法的,但我从来没有在野外看到过,我在野外看到过一些非常精彩/恐怖的代码。这似乎是一种代码
类怪人类
{
私有void Hello(字符串名称)
{
WriteLine(“你好,{0}!”,name);
}
公共字符串名
{
集合{Hello(name);}
}
}
换句话说,该属性有一个setter,但没有getter,它是只写的
我想我想不出为什么这是非法的,但我从来没有在野外看到过,我在野外看到过一些非常精彩/恐怖的代码。这似乎是一种代码气味;似乎编译器应该给我一个警告:
CS83417:属性“Name”似乎完全无用且愚蠢。糟糕的程序员!考虑用方法替换。< /P>
但也许我做这件事的时间还不够长,或者在一个太窄的领域里工作,看不到任何有效使用这种结构的例子
是否存在仅写属性的实际示例,它们要么不能被直接的方法调用替换,要么会变得不那么直观?仅写属性实际上非常有用,我经常使用它们。这都是关于--限制对对象组件的访问。您通常需要为需要在内部使用的类提供一个或多个组件,但没有理由让其他类可以访问这些组件。这样做只会使您的类更加混乱(“我是使用这个getter还是这个方法?”),而且您的类更有可能被篡改或绕过其真正用途
有关这方面的有趣讨论,请参阅。我并不像这篇文章的作者那样对这件事很坚决,但我认为这是一件值得思考的事情。我通常使用Setter,但很少使用getter。从技术上讲,仅Setter属性本身并没有什么问题。Setter可以进行一些验证,也许其他一些方法(public或private)也可以依赖它 例如:
class-SomeClass{
私有int_someVar;
SomeClass(int-someVar){
如果(someVar>0)\u someVar=someVar;
}
公共int-SomeVar{
设置{if(value>0)\u someVar=value;}
}
公共字符串函数(){
return“这是一个使用_someVar”+_someVar的重要函数;
}
}
因此,声明本身可能合法有效。虽然你的方法体是一个巨大的代码气味,但这不是编译器要关心的工作。我对这个问题的第一反应是:“方法呢?”
我认为只写属性在几种情况下都很有用。例如,当您不想公开内部表示(封装)时,同时允许更改对象的状态。JavaUTI.RAPID是一个很好的例子。 < P>不,我可以想象任何情况下它们都不能被替换,尽管可能有人认为它们更可读。 假设情况:
CommunicationDevice.Response=“你好,世界”
而不是
CommunicationDevice.SendResponse(“你好,世界”)
主要工作是执行IO副作用或验证
有趣的是,VB.NET甚至为这种奇怪的属性设置了自己的关键字;)
Public WriteOnly属性Foo()为整数
设置(值为整数)
' ... '
端集
端属性
尽管来自外部的许多“只写”属性实际上都有一个私有getter。代码分析(又称FxCop)确实为您提供了一个诊断:
:Microsoft。设计:因为
属性'WeirdClass.Name'是只写的,
添加一个具有
大于或等于的可访问性
等于其setter或将其转换为
属性转换为方法
就我而言,他们没有。每次我使用一个只写属性作为快速攻击,我后来都会后悔。通常我会得到一个构造函数或一个完整的属性
当然,我想证明一个否定的观点,所以也许我遗漏了一些东西 在XNA项目中,我有类似于以下内容的代码。正如您所看到的,Scale是只写的,它很有用并且(合理地)直观,而读取属性(get)对它来说没有意义。当然可以用方法替换它,但我喜欢它的语法
公共类MyGraphicalObject
{
公共双ScaleX{get;set;}
公共双尺度{get;set;}
公共双尺度{get;set;}
公共双刻度{set{ScaleX=ScaleY=ScaleZ=value;}
//更多。。。
}
当你不应该读你写的东西时,只写东西是有用的
例如,在屏幕上绘图时(这正是桌面窗口管理器在Windows中所做的):你当然可以在屏幕上画图,但是你永远不需要读回数据(更不用说期望得到和以前一样的设计了) 现在,只写属性是否有用(与方法相反),我不确定它们的使用频率。我想您可以想象一种具有“BackgroundColor”属性的情况,在这种情况下,向其写入设置屏幕的背景色,但读取没有意义(必要)。
所以我不确定这一部分,但总的来说,我只想指出,在某些情况下,您只写数据,而从不读取数据。只写属性的一个用途是支持setter依赖项注入,这通常用于可选参数 假设我上过一节课:
public class WhizbangService {
public WhizbangProvider Provider { set; private get; }
}
WhizbangProvider不打算被外部世界访问。我从来不想与服务提供商进行交互,因为它太复杂了。我需要一门像惠兹班斯这样的课
service.Provider = new FireworksShow();
service.Start();
service.Stop();
service.Provider = new FountainDisplay(new StringOfLights(), 20, UnitOfTime.Seconds);
service.Start();
public abstract class DisplayService {
public WhizbangProvider Provider { set; private get; }
}
public class WhizbangService : DisplayService { }
public abstract class DisplayService {
public WhizbangProvider Provider;
protected DisplayService(WhizbangProvider provider) {
Provider = provider ?? new DefaultProvider();
}
}
public class WhizbangService : DisplayService {
public WhizbangService(WhizbangProvider provider)
: base(provider)
{ }
}
public AllowedAttribute: AuthorizeAttribute
{
public AllowedAttribute(IStore store) {...}
private IStore Store { get; set; }
...
}
public AllowedAttribute: AuthorizeAttribute
{
[Inject] public IStore Store { private get; set; }
...
}
public int MyFancyWepapiMethod([FromBody]CallParams p) {
return p.MyIntPropertyForAjax.HasValue ? p.MyIntPropertyForAjax.Value : 42;
}
public class CallParams
{
public int? MyIntPropertyForAjax;
public object TryMyIntPropertyForAjax
{
set
{
try { MyIntPropertyForAjax = Convert.ToInt32(value); }
catch { MyIntPropertyForAjax = null; }
}
}
}
var callparameter = {
TryMyIntPropertyForAjax = 23
}
public partial class ShowMeTheTime : Page, ICurrentTimeView
{
protected void Page_Load(object sender, EventArgs e)
{
CurrentTimePresenter presenter = new CurrentTimePresenter(this);
presenter.InitView();
}
public DateTime CurrentTime
{
set { lblCurrentTime.Text = value.ToString(); }
}
}
public void InitView()
{
view.CurrentTime = DateTime.Now;
}