【问题标题】:Why can't you call methods with c# object initializer syntax? [closed]为什么不能使用 c# 对象初始化器语法调用方法? [关闭]
【发布时间】:2011-06-04 01:00:16
【问题描述】:

为什么不能用 c# 对象初始化语法调用方法?

在我看来,属性设置器是按照它们在语法中设置的顺序被调用的,那么为什么不允许调用方法呢?如果有充分的理由,我很想念它。

编辑

我意识到方法和属性之间的语义差异以及技术上的相似之处。这个问题的目的是为了探究一个很好的技术原因,即他们没有包含该功能。

这个。 __curious_geek,我听到你在说什么,但我敢肯定他们没有包含一些功能,因为它在技术上不可行。

这就是我所追求的。压倒性的不受欢迎的语气响亮而清晰。 Stackoverflow 不再是“问答网站”,而是“捍卫您的问题网站”。

编辑 2

示例用法:

var mySuperLongVariableNameThatIDontWantToTypeOverAndOverAgainAndIsntThatTheWholePointAnyway  = new Thingy
    {
        Name = "Marty McFly",
        AddChildren("Biff","Big Bird","Alf"),
        // 1000 other properties and method calls.....
    }

【问题讨论】:

  • 如果我不得不猜测原因,我会说是因为所有功能都从 -100 点开始,而且它没有成功。
  • 如果您有需要在对象初始化期间调用的方法,那么您应该从构造函数中调用它们,而不是将其留给使用您的类的开发人员。
  • 这是一个主观问题,对于不存在的事物没有明确的答案。
  • re Edit2:如果AddChildren() 需要或更改名称属性怎么办?所有类型的错误场景都成为可能,但收益微乎其微。
  • 这是一个有趣的想法。当然,为了节省打字,你可以先var x = mySuperLong... 然后x.AddChildren(...

标签: c# .net


【解决方案1】:

答案就在名称中——对象 initializer 语法是对对象的初始状态进行可视化分组的语法糖。方法改变了对象的状态,所以一旦改变,它就不再是初始状态了。

例如:假设你买了一辆车。这是一辆红色轿跑车,行驶里程为 55,000 英里。然后,您决定驾驶它。最终行驶了 55,500 英里。它已经从初始状态发生了变化:

var c = new Car() {Color = "Red",
                   Style = Styles.Coupe,
                   Mileage = 55000};
// c.Mileage is 55,000
c.Drive();
// c.Mileage is 55,500

在这个有点做作的示例中,该方法具有副作用,因此将对象从其初始 55,000mi 状态更改为 55,500mi 状态。这与购买一辆行驶里程为 55,500 英里的汽车不同。

【讨论】:

  • 属性设置器也可以改变状态。
  • @Ronnie 这在技术上是正确的——正如 Yuck 的回答所示——但属性背后的想法是它们不是方法;他们不会隐藏他们正在做的事情,并且可能会导致看不见的变化
  • 属性旨在“读取、写入或计算私有字段的值”[msdn.microsoft.com/en-us/library/x9fsa0sw.aspx],因此虽然它们可能有副作用,但正确设计的属性应该将这些副作用限制在那些这是设置该值所必需的(因此,它仍然与初始值的想法相吻合)。
  • 顺便说一句,我想指出,根据对属性的描述,编写任何 Silverlight 或 WPF MVVM 视图模型的优秀开发人员每天都在践踏他们的意图。 :)
【解决方案2】:

如果你真的想要这样做,我想你可以作弊......

class C {
    int BadProperty {
        set {
            SomeMethod(value);
        }
    }

    void SomeMethod(int value) {
        // here is where you do really, really bad things
    }
}

那就这样称呼吧!

var fail = new C { BadProperty = 1 };

【讨论】:

  • Bad,Smelly ...我们是否希望在框架中使用它+1
  • 我真的不想这样做。我不是在问如何完成它。
  • 您也可以方法返回父类型.. Person SetPassword(string newPassword)... Person p = new Person() { FirstName="Bob", LastName="Smith"}.SetPassword( txtPassword.Text);
【解决方案3】:

如果方法失败了怎么办?基本思想是,它只是一个语法糖。 Eric Lippert 多次被问及“为什么 C# 不支持功能 X?”。他的回答总是

“因为没有人设计,指定, 实施、测试、记录和 提供了该功能。” - Eric Lippert。

【讨论】:

  • 我很惊讶他还没有回答这个问题:)
  • 如果属性设置器失败了怎么办?
  • 我曾经给 eric 写了一封电子邮件,在回复中他解释了这个答案。我问他这个。 stackoverflow.com/questions/1021190/…
【解决方案4】:

这都是关于订单的,必须使用所有字段和所有声明的方法来初始化类,然后才能保证安全地运行方法。

【讨论】:

  • 在我看来,这个答案比当前选择的答案更有效。
【解决方案5】:

您可以使用命名参数调用方法,如果这是您所要求的:

someMethod(param1: "Hello World", param2: "Some Other Value");

【讨论】:

  • 我相信他是在问关于在类初始化程序中调用方法,例如var x = new Foo { Name = "Bar", FooBar() };
  • 啊,是的,这有点傻。
猜你喜欢
  • 2020-09-02
  • 2018-12-24
  • 1970-01-01
  • 2013-10-23
  • 2013-12-31
  • 2013-07-27
  • 1970-01-01
  • 1970-01-01
  • 2010-10-03
相关资源
最近更新 更多