我最近才知道C#'事件'确实是.老实说,这不是真的.综上所述我的发现:该事件的关键字很简单,只适用于委托的改性剂.
因此,事件的所有"魔力"都是代表的操作.而已.我已经阅读了很多Microsoft文档,但没有任何句子以这种方式如此简洁地总结.为了继续我的发现,委托,类和结构都处于同一"级别".它们是定义"对象"的方法.我并不是指类型中的"对象",而是"某事"的封装概念.就像在面向对象编程时使用"对象"这个词一样.
无论如何,'对象'有一些修饰符.例如,密封,只读,虚拟,静态等...此列表可在此处找到.在委托的情况下,它有一个名为event的额外的.事件使得当委托被声明为类的一部分时,它只根据给予事件的访问修饰符公开add和remove方法.这些方法的定义与获取和设置属性的性质类似.委托的其他操作(赋值,读访问,方法调用等)仅允许在声明事件委托的类中.我感兴趣的另一件事是,所有委托都有方法Invoke,BeginInvoke和EndInvoke,但你无法导航到在Visual Studio中查看它们,也无法找到描述它们的文档......
好的.因此,在了解了所有这些之后,除了修改委托的访问方式之外,使用event关键字有什么好处?看起来,在许多情况下,我最好只是声明一个没有event关键字的委托.我最近遇到的一种情况是我想创建一个包含2个事件的抽象基类.从这个基类派生的任何类都应该能够使用类似于它们自己的事件,类似于暴露给派生类的类的任何其他对象(也就是非私有的,除非派生类在另一个程序集,并且对象被声明为内部).
基本上,我希望派生类将这些事件用作自己的事件.执行此操作的唯一方法是将事件的支持变量公开为受保护,因此派生类可以引发事件.看看代码,这看起来很愚蠢,因为我基本上定义了两次委托; 曾经作为一个受保护的领域,另一个作为公共事件.我想,
在构造函数中创建一个名为Event的类,并且在构造函数中有一个Action参数,我会不会更好?返回的操作等同于许多人作为委托的扩展方法所做的提升,它检查委托是否为空,然后调用委托.Event上唯一的公共方法是Add和Remove,用于追加委托并从底层委托中删除它们(+ =, - =).类可以将这些事件作为属性,例如,
public Event SomethingHappened { get; private set; }
Run Code Online (Sandbox Code Playgroud)
这样只有那个类才能重新分配事件.或者公共只读字段也同样有效.从构造函数返回的out参数由类存储,并在类想要引发事件时调用.我知道这是一个很好的解决方法,但它会完成工作,并允许事件不仅作为参数传递,而且允许派生类在基类将其定义为受保护时调用Raise方法.
TLDR:
今天我在创建一个struct包含大量数据的时候遇到了这个问题.这是一个例子:
public struct ExampleStruct
{
public int Value { get; private set; }
public ExampleStruct(int value = 1)
: this()
{
Value = value;
}
}
Run Code Online (Sandbox Code Playgroud)
看起来很好,花花公子.问题是当我尝试使用此构造函数而未指定值并希望对参数使用默认值1时:
private static void Main(string[] args)
{
ExampleStruct example1 = new ExampleStruct();
Console.WriteLine(example1.Value);
}
Run Code Online (Sandbox Code Playgroud)
此代码输出0但不输出1.原因是所有结构都具有公共参数构造函数.所以,就像我调用this()我的显式构造函数一样,在Main同样的事情发生在new ExampleStruct()实际调用ExampleStruct()但不调用的地方ExampleStruct(int value = 1).因为它这样做,它使用int的默认值为0 Value.
更糟糕的是,我的实际代码是检查该int value = 1参数是否在构造函数中的有效范围内.将其添加到ExampleStruct(int value = 1)上面的构造函数中:
if(value < 1 || …Run Code Online (Sandbox Code Playgroud) 我有一个C#控制台应用程序,我试图在其中做一些ASCII艺术.但是,我想要使用的一些字符是Unicode.所以,我正在搜索互联网/ SO,并找不到关于如何在C#控制台应用程序中将控制台设置为Unicode的综合答案.
TDLR:如何将C#控制台应用程序中的控制台设置为Unicode?
编辑:我在搜索与此问题无关的内容后确实找到了这篇文章.
为什么要允许编译这段代码?
public abstract class AbstractPrivateBase
{
private AbstractPrivateBase() { }
}
Run Code Online (Sandbox Code Playgroud)
继承者无法实例化自己.因此,没有办法从这个类派生出来.我觉得Visual Studio(甚至Resharper)应该显示一个错误,说明"抽象类不能只包含私有构造函数".因为在语言中允许这样做是没有意义的.
唯一可能的用法是此类包含静态成员.如果是这种情况,一个友好的警告说明"只有私有构造函数的抽象类可以变成静态的".因为没有办法访问任何其他成员而不是静态成员.