C# 在对象初始值设定项中分配事件

C# 在对象初始值设定项中分配事件,c#,.net,events,delegates,object-initializers,C#,.net,Events,Delegates,Object Initializers,为什么不能在C#中的对象初始值设定项中指定事件和属性?这样做似乎很自然 var myObject = new MyClass() { Property = value, Event1 = actor, // or Event2 += actor }; 还是有一些我不知道的技巧?您只能对其所有者类之外的事件使用操作符+=或-= 公共类数据 { 公共事件处理程序OnSave=(s,e)=> { //做点重要的事

为什么不能在C#中的对象初始值设定项中指定事件和属性?这样做似乎很自然

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

还是有一些我不知道的技巧?

您只能对其所有者类之外的事件使用操作符
+=
-=

公共类数据
{
公共事件处理程序OnSave=(s,e)=>
{
//做点重要的事!
};
公共作废保存()
{
OnSave(这个,空);
//存钱
}
}
//课外
数据数据=新数据{OnSave=null}//编译错误
data.OnSave=其他方法//编译错误
data.OnSave+=MyCustomActionsOnSave//好啊
data.Save();

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

就外部契约而言,事件没有setter,只有添加和删除方法-订阅者可以从事件中注册和注销,发布对象通过“引发”事件来决定何时调用回调。因此,“分配一个事件”的想法通常是没有意义的

但是,当您在类中声明事件时,C#编译器为您提供了真正方便的功能:当您不提供自己的实现时,它会为您创建一个私有的、支持委托字段,以及相应的添加/删除实现。这允许您在类内“设置事件”(实际上是支持字段),而不是在类外。要理解这一点,请考虑:

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 };
    }
}
这并没有使C#6或C#7(从最初的问题开始),但还没有决定反对。GitHub上存在跟踪语言提案的问题。您可以在那里投票支持该功能,也可以通过链接进入之前关于该功能的讨论

如果您想查看此功能,请对该问题竖起大拇指,以帮助提高其可见性

建议的语法是:

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

这与限制无关。属性有setter方法和私有支持字段,但是对象初始值设定项可以很好地使用这些方法。他(想要)使用
+=
。如果您仍然感兴趣,这个功能将添加到下一个语言版本中,请看我的建议: