Ale*_*kov 30 c# collection-initializer
我在阅读 Avalonia 源代码时发现了这句话:
return new MenuFlyoutPresenter
{
[!ItemsControl.ItemsProperty] = this[!ItemsProperty],
[!ItemsControl.ItemTemplateProperty] = this[!ItemTemplateProperty]
};
Run Code Online (Sandbox Code Playgroud)
我从未见过这样的语法。如果没有索引属性或 this[] 访问器,这些括号会做什么?如果它们引用的属性不是 bool,为什么它们会用感叹号否定?也许是某种空检查?
代码本身包含在以下 cs 文件中:
https://github.com/AvaloniaUI/Avalonia/blob/master/src/Avalonia.Controls/Flyouts/MenuFlyout.cs
我跟踪了代码,但无法理解该语法的作用。
can*_*on7 35
这里发生了一些事情。
首先,语法:
var menu = new MenuFlyoutPresenter
{
[key] = value,
};
Run Code Online (Sandbox Code Playgroud)
是一个集合初始值设定项,是以下形式的简写:
var menu = new MenuFlyoutPresenter();
menu[key] = value;
Run Code Online (Sandbox Code Playgroud)
该索引器在这里定义为:
public IBinding this[IndexerDescriptor binding]
{
get { return new IndexerBinding(this, binding.Property!, binding.Mode); }
set { this.Bind(binding.Property!, value); }
}
Run Code Online (Sandbox Code Playgroud)
所以key存在一个IndexerDescriptor,并且value是一个IBinding。
那么,这件事是怎么回事呢?
!ItemsControl.ItemsProperty
Run Code Online (Sandbox Code Playgroud)
我们可以从您的链接中看到这ItemsProperty是一个DirectProperty<TOwner, TValue>, 并且最终在此处!实现了运算符:
public static IndexerDescriptor operator !(AvaloniaProperty property)
{
return new IndexerDescriptor
{
Priority = BindingPriority.LocalValue,
Property = property,
};
}
Run Code Online (Sandbox Code Playgroud)
Avalonia 似乎喜欢重载运算符,例如!和~来做你可能意想不到的事情(通常会使用一个方法)。在本例中,他们使用!on anAvaloniaProperty作为访问该属性绑定的简写。
Mat*_*son 11
演示允许此语法的方法的相对简单的类是:
public sealed class Demo
{
public Demo this[Demo index] // Indexer
{
get => !index;
set {} // Not needed to demonstrate syntax.
}
public static Demo operator !(Demo item) => item;
public Demo ItemsProperty => _empty;
public Demo ItemTemplateProperty => _empty;
public Demo SomeMethod(Demo ItemsControl)
{
return new Demo
{
[!ItemsControl.ItemsProperty] = this[!ItemsProperty],
[!ItemsControl.ItemTemplateProperty] = this[!ItemTemplateProperty],
};
}
static Demo _empty = new();
}
Run Code Online (Sandbox Code Playgroud)
需要注意的一些事项:
Demo实现operator!允许!运算符用于该类型的值(例如初始化!ItemsProperty中的
SomeMethod())。Demothis实现一个索引器,它允许在集合初始值设定项的右侧使用索引(通过)。[x] = y使用 中使用的集合初始化语法SomeMethod()。operator()!它是运算符与索引器的组合this[Demo],从而启用了该语法。