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

发布于 2024-09-28 17:00:27 字数 232 浏览 4 评论 0原文

为什么不能在 C# 中的对象初始值设定项中将事件与属性一起分配?这样做似乎是那么自然。

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

还是有什么我不知道的技巧?

Why isn't it possible to assign events along with properties in object initializers in C#? It seems to be so natural to do so.

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

Or is there some trick that I don't know of?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤千羽 2024-10-05 17:00:27

这并没有使 C# 6 或 C# 7 (自最初的问题以来),但尚未决定反对。 GitHub 上有一个跟踪该语言提案的问题。您可以在那里投票,也可以点击链接进入之前围绕该功能的讨论。

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

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

建议的语法是:

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

This didn't make C# 6 or C# 7 (since the original question), however it hasn't been decided against. There is an issue on GitHub that tracks the language proposal. You can vote for it there, as well as follow links into previous discussion around the feature.

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

If you'd like to see this feature, add a thumbs-up to the issue to help raise its visibility.

The proposed syntax is:

var timer = new DispatcherTimer {
    Tick += delegate {},
    Interval = TimeSpan.FromSeconds(1d),
};
如梦初醒的夏天 2024-10-05 17:00:27

就外部合约而言,事件没有 setter,只有 addremove 方法 - 订阅者可以注册和取消注册事件,发布对象通过“引发”事件来决定何时调用回调。因此,“分配事件”的想法一般来说是没有意义的。

然而,当您在类中声明事件时,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 };
    }
}

As far the external contract is concerned, an event doesn't have a setter, only add and remove methods - subscribers can register and unregister from the event, and the publishing object decides when to invoke the callbacks by 'raising' the event. Consequently, the idea of "assigning an event", in general, is meaningless.

However, when you declare an event in a class, the C# compiler provides you with what is really a convenience-feature: when you don't provide your own implementation, it creates a private, backing delegate-field for you, along with the appropriate add / remove implementations . This allows you to "set the event" (really the backing field) within the class, but not outside it. To understand this, consider:

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 };
    }
}
人生百味 2024-10-05 17:00:27

您只能将运算符 +=-= 用于其所有者类之外的事件。

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 将不再是一个事件,而是一个普通的委托。然后你可以做任何事情,包括在类外赋值。

You can only use the operators += or -= to an event outside its owner class.

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();

You can't remove the OnSave action defined in the class. You can only add/remove your own OnSave actions outside the class. If you remove the event keyword, the OnSave will be no longer an event, but an ordinary delegate. Then you can do anything including assigning value outside the class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文