在对象初始化器中分配事件

26

为什么在C#的对象初始化器中不能同时分配事件和属性?这样做似乎很自然。

var myObject = new MyClass()
     {
        Property = value,
        Event1 = actor,
        // or
        Event2 += actor
     };  

还有其他窍门我不知道吗?


看起来这个功能将会在下一个语言版本中添加。http://roslyn.codeplex.com/wikipage?title=Language+Feature+Status - Zarat
如果您仍然感兴趣,请查看我在此处的建议:http://stackoverflow.com/questions/24951619/add-event-handler-during-object-initialization/37994490#37994490 - Vladislav Rozanov
3个回答

14

自原问题提出以来,C#6或C#7都没有这样做,但也没有反对。 GitHub上有一个跟踪语言提案的问题。 在那里,您可以为其投票,并跟随链接进入围绕该功能的先前讨论。

https://github.com/dotnet/csharplang/issues/307

如果您想看到此功能,请点赞该问题以帮助提高其可见性。

所提议的语法是:

var timer = new DispatcherTimer {
    Tick += delegate {},
    Interval = TimeSpan.FromSeconds(1d),
};

5
就外部契约而言,事件没有setter,只有addremove方法 - 订阅者可以注册和注销事件,而发布对象决定何时通过“触发”事件来调用回调函数。因此,“分配事件”的想法在一般情况下是没有意义的。
但是,当你在一个类中声明一个事件时,C#编译器为你提供了一个真正方便的功能:当你不提供自己的实现时,它会为你创建一个私有委托字段,并提供适当的add / remove实现。这允许你在类内部“设置事件”(真正的备份字段),但在类外部却不能这样做。为了理解这一点,请考虑:
public class Foo
{
    // implemented by compiler
    public event EventHandler MyEvent;

    public static Foo FooFactory(EventHandler myEventDefault)
    {
       // setting the "event" : perfectly legal
       return new Foo { MyEvent = myEventDefault }; 
    }
}

public class Bar
{
    public static Foo FooFactory(EventHandler myEventDefault)
    {
        // meaningless: won't compile
        return new Foo { MyEvent = myEventDefault };
    }
}


public class Baz
{
    // custom implementation
    public event EventHandler MyEvent
    {      
        add { }  // you can imagine some complex implementation here
        remove { } // and here
    }

    public static Baz BazFactory(EventHandler myEventDefault)
    {
        // also meaningless: won't compile
        return new Baz { MyEvent = myEventDefault };
    }
}

10
这与限制无关。属性有setter方法和私有后备字段,但对象初始化程序仍能正常使用它们。 - Ben Voigt

4
你只能在其所有者类之外的事件中使用 +=-= 操作符。
public class Data
{
    public event EventHandler OnSave = (s,e) => 
        {
            //do something important!
        };

    public void Save()
    {
        OnSave(this,null);
        //do save
    }
}

//outside the class
Data data = new Data { OnSave = null }; //compile error
data.OnSave = SomeMethodElse;  //compile error
data.OnSave += MyCustomActionsOnSave;  //ok
data.Save();

您无法删除类中定义的OnSave操作。您只能在类外添加/删除自己的OnSave操作。如果删除event关键字,则OnSave将不再是事件,而是普通的委托。然后您可以执行包括在类外赋值的任何操作。


他想要使用 += - Ben Voigt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接