我在这里创建了这个程序,以展示我想要做的事情。您可以看到除了应该调用_OnSell
事件的行之外,所有代码都已写入。 (第21行〜)
using System;
namespace example
{
public class Car
{
public int Price;
public string ModelName;
private Boolean Sold;
public delegate void SellEventHandler(string str);
public event SellEventHandler _OnSell;
public Boolean _Sold
{
get { return Sold; }
set
{
Sold = value;
if (Sold == true)
{
// INVOKE _OnSell EVENT HERE !!
}
}
}
public void OnSell(string str)
{
Console.WriteLine("library stuff");
}
public Car(int price, string modelname)
{
Price = price;
ModelName = modelname;
Sold = false;
_OnSell = OnSell;
}
}
public class Program
{
static void Main()
{
Program p1 = new Program();
Car _car = new Car(6000, "audi");
_car._OnSell += p1.Car_OnSell;
_car._Sold = Console.ReadLine() == "true" ? true : false;
Console.ReadLine();
}
public void Car_OnSell(string message)
{
Console.WriteLine("user stuff");
}
}
}
每当值_car._OnSell
发生变化时,我都会尝试调用事件_car._Sold
。我怎么能在C#中做到这一点?
答案 0 :(得分:2)
请参阅Handling and Raising Events
因此,按照提供的示例,代码如下所示。
请注意,名称会更改为更清晰的公共API以及事实上的一致性和命名标准。
public class Car
{
// Note use of `sender` convention
public delegate void SoldEventHandler(object sender, string str);
// Events normally do not have the `On` prefix, also the event
// name is normally the sense-correct verb such as `Sold` or `Selling`.
public event SoldEventHandler Sold;
private bool _isSold;
public bool IsSold
{
get { return _isSold; }
set
{
if (value && !_isSold) {
// Only sell when false -> true
OnSold("whatever string it is supposed to be");
}
_isSold = value;
}
}
// "Typically, to raise an event, you add a method that is marked as protected and virtual.
// .. Name this method OnEventName; for example, OnDataReceived."
public virtual void OnSold(string str)
{
// Follow the conventions in the link - ask on SO as to why the local
// variable and check for null are important/necessary.
var handler = Sold;
if (handler != null) {
handler(this, str);
}
}
// ..
_car.Sold += p1.Car_OnSell;
_car.IsSold += Console.ReadLine() == "true" ? true : false;
在大多数情况下,我建议让事件采用(object sender, EventArgs args)
,因为它会使事件的未来更改更加灵活 - 这也是链接中讨论的 。
答案 1 :(得分:2)
正如评论者提供的链接中所解释的那样(但遗憾的是,在发布的第一个答案中没有解释),您需要更改代码,使其看起来更像这样:
public Boolean _Sold
{
get { return Sold; }
set
{
Sold = value;
if (Sold)
{
OnSell("your string here");
}
}
}
public void OnSell(string str)
{
SellEventHandler handler = _OnSell;
if (handler != null)
{
handler(str);
}
Console.WriteLine("library stuff");
}
以上将有效。但是,值得注意的是,您在几个重要方面偏离了正常的.NET事件处理习惯用法:
EventHandler<T>
结构。正常的.NET方法签名提供了两个优点:识别发件人,以及基于事件参数的标准化EventArgs
数据结构。true
时才会引发事件。更典型的,坦率地说更有用的是“改变”的事件。例如。 SoldChanged
,会在Sold
属性的值发生更改时随时生成。遵循标准事件处理习惯用法的一个更好的好处是,您的类将与.NET中的大多数(如果不是全部)常见数据绑定实现一起使用。在这里实现它的方式,您的事件在使用方式上非常有限。在这种情况下可能没什么问题,但作为一般规则,提供更灵活的实现非常容易,你也可以养成这样做的习惯。
答案 2 :(得分:1)
试试这个:
_OnSell( "some message" );