Подтвердить что ты не робот

Назначение событий в инициализаторе объекта

Почему не возможно назначать события вместе со свойствами в инициализаторах объектов в С#? Кажется, это так естественно.

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

Или есть какой-то трюк, о котором я не знаю?

4b9b3361

Ответ 1

Что касается внешнего контракта, то, это событие не имеет сеттера, только add и remove Методы - абоненты могут зарегистрироваться и разрегистрировать от события, и объект публикации решает, когда для вызова функции обратного вызова с помощью "повышение" события. Следовательно, идея "присвоения события" вообще не имеет смысла.

Однако, когда вы объявляете событие в классе, компилятор С# предоставляет вам то, что действительно является удобной функцией: когда вы не предоставляете свою собственную реализацию, она создает для вас приватное, поддерживающее поле для делегатов, наряду с соответствующими реализациями 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 };
    }
}

Ответ 2

Вы можете использовать операторы += или -+ для события вне его класса владельца.

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 будет уже не событием, а обычным делегатом. Затем вы можете сделать что угодно, включая назначение значения вне класса.

Ответ 3

Это не делало С# 6 или С# 7 (с оригинального вопроса), однако это не было принято. В GitHub есть проблема, которая отслеживает языковое предложение. Вы можете проголосовать за него там, а также следовать ссылкам в предыдущем обсуждении этой функции.

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

Если вы хотите увидеть эту функцию, добавьте превью на эту проблему, чтобы повысить ее видимость.

Предлагаемый синтаксис:

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