问题 为什么不能使用c#object initializer语法调用方法? [关闭]


为什么不能使用c#object initializer语法调用方法?

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

编辑

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

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

这就是我所追求的一切。听到的压倒性的不受欢迎的声音响亮而清晰。 Stackoverflow不再是“问答网站”,而是“保护您的问题网站”。

编辑2

样品用法:

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

9048
2018-06-03 15:44


起源

如果我不得不猜测为什么,我会说它因为所有功能都从-100点开始,并没有进行削减。 - asawyer
如果你有在对象初始化期间需要调用的方法,那么你应该从构造函数中调用它们而不是将它留给使用你的类的开发人员。 - Lazarus
这是一个主观问题,没有一个关于某些不存在的东西的明确答案。 - Jodrell
重新编辑2:如果 AddChildren() 需要或更改Name属性?所有类型的错误情况都成为可能,收益甚微。 - Henk Holterman
这是一个有趣的想法。当然,为了节省你可以做的打字 var x = mySuperLong... 然后 x.AddChildren(... - Jodrell


答案:


答案在于名称 - 对象 初始化 语法是语法糖,可以直观地分组对象的初始状态。方法改变对象状态,所以一旦改变,它就不再是了 初始 州。

例如:说你买车。这是一辆红色轿跑车,上面有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英里的汽车不同。


6
2018-06-03 15:49



财产制定者也能够改变国家。 - Ronnie Overby
@Ronnie在技术上是正确的 - 正如Yuck的答案所示 - 但属性背后的想法是它们不是方法;他们不会隐藏他们正在做的事情,并可能导致看不见的变化 - NickAldwin
属性旨在“读取,写入或计算私有字段的值”[ msdn.microsoft.com/en-us/library/x9fsa0sw.aspx 因此,虽然它们可能有副作用,但正确设计的属性应该将这些副作用限制为仅设置该值的那些副作用(因此,它仍然符合初始值的想法)。 - NickAldwin
顺便说一句,我想指出的是,根据对属性的描述,他们的意图每天都被优秀的开发人员编写任何Silverlight或WPF MVVM视图模型。 :) - Ronnie Overby


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

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 };

6
2018-06-03 15:55



坏,臭...我们是否希望在框架中+1 - Jodrell
我真的不想这样做。我不是在问如何实现它。 - Ronnie Overby
你也可以返回父类型的方法.Person SetPassword(string newPassword)... Person p = new Person(){FirstName =“Bob”,LastName =“Smith”} .SetPassword(txtPassword.Text); - Ryan Mann


如果方法失败怎么办?基本的想法是,它只是一个语法糖。 Eric Lippert很多时候被问到“为什么C#不支持X功能?”。他的答案总是如此

“因为没人设计,指定,   实施,测试,记录和   发布了这个功能。“ - Eric Lippert。


2
2018-06-03 16:00



我很惊讶他还没有回答这个问题:) - NickAldwin
如果属性设置器失败怎么办? - Ronnie Overby
@NickAldwin - 我也是。 - Ronnie Overby
我曾经给埃里克写了一封电子邮件,他在回复中解释了这个答案。我问他这个。 stackoverflow.com/questions/1021190/... - this. __curious_geek


这就是全部 命令,必须先使用所有字段和所有声明的方法初始化Class,然后才能保证安全地运行方法。


1
2018-06-03 16:04





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

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

0
2018-06-03 15:48



我相信他要求在类初始值设定项中调用方法,例如 var x = new Foo { Name = "Bar", FooBar() }; - Dan J
啊,那么是的,那有点傻。 - Tejs