考虑以下扩展方法:
public static void Toggle(this ref bool @bool) => @bool = !@bool;
public static void Toggle2(ref this bool @bool) => @bool = !@bool;
Run Code Online (Sandbox Code Playgroud)
这些只是切换 ref 布尔变量值。测试:
class Foo
{
private bool _flag;
public void DoWork()
{
_flag.Toggle();
Console.WriteLine(_flag);
_flag.Toggle2();
Console.WriteLine(_flag);
}
}
Run Code Online (Sandbox Code Playgroud)
我们得到:
True
False
Run Code Online (Sandbox Code Playgroud)
问题:选择一种语法或另一种语法是否存在隐藏的差异?
这可能是一个愚蠢的问题......但我无法找到另一个可以回答它的问题,也找不到可以帮助我实现我想要的目标的帖子。
我有以下 XAML:
<Menu>
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="Item1" />
<Separator VerticalContentAlignment="Stretch" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" />
<MenuItem Header="Item2" />
</Menu>
Run Code Online (Sandbox Code Playgroud)
在我现实生活中的业务案例中,标题更加复杂,包含图像和其他一些内容。
问题是上面的 xaml 产生以下输出:
正如您所看到的,分隔符没有拉伸。这似乎是一个非常简单的任务......但我还没有找到解决方案。
我尝试过将样式设置为ItemContainerStyle我赋予HorizontalContentAlignment值的位置Stretch,但它不起作用。
我有一个组合框,并希望将其ItemsSource绑定到IEnumerable<(string,string)>.如果我没有设置DisplayMemberPath,那么它可以工作,它在下拉区域显示调用ToString()项目的结果.然而,当我设置DisplayMemberPath="Item1"它不再显示任何东西.我做了以下示例,您可能会看到如果我使用经典Tuple类型,它会按预期工作.
调试时我已经检查过valuetuple还有Item1和Item2作为属性.
我的XAML:
<Window x:Class="TupleBindingTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Loaded="MainWindow_OnLoaded"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<ComboBox x:Name="TupleCombo" Grid.Row="0" VerticalAlignment="Center"
DisplayMemberPath="Item1" />
<ComboBox x:Name="ValueTupleCombo" Grid.Row="1" VerticalAlignment="Center"
DisplayMemberPath="Item1" />
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
我的代码隐藏:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
namespace TupleBindingTest
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
private IEnumerable<Tuple<string, string>> GetTupleData()
{
yield return Tuple.Create("displayItem1", "valueItem1");
yield return Tuple.Create("displayItem2", "valueItem2");
yield return Tuple.Create("displayItem3", "valueItem3");
}
private IEnumerable<(string, …Run Code Online (Sandbox Code Playgroud) 我有以下不编译的代码:
public class Outer
{
public Inner MyField = new Inner(); //error here: "field type is less accessible than field"
private class Inner
{
public string Message = "Hello";
}
}
Run Code Online (Sandbox Code Playgroud)
我必须能够像这样使用这个类:
var MyObject = new Outer();
Console.WriteLine(MyObject.MyField.Message); //should output "Hello"
Run Code Online (Sandbox Code Playgroud)
"内部"必须只能在"外部"内实例化,所以不应该允许:
var MyObject = new Outer.Inner(); //I do not want users to be able to instantiate "Inner" directly
Run Code Online (Sandbox Code Playgroud) 考虑以下方法:
public object Foo(bool flag)
{
if (flag)
return (new object(), new object());
return (null, new object()); //Compiler error over here!!
}
Run Code Online (Sandbox Code Playgroud)
这不会编译显示我在这个问题的标题中提到的错误。我可以通过如下所示的演员来解决这个问题:
public object Foo(bool flag)
{
if (flag)
return (new object(), new object());
return ((object)null, new object());
}
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好。奇怪的部分和我问这个的原因是,如果我改变语法并使用三元运算符而不是像这样的 if-else 语句:
public object Boo(bool flag) => flag
? (new object(), new object())
: (null, new object());
Run Code Online (Sandbox Code Playgroud)
那么就不需要演员表了!!!为什么?恕我直言,编写该方法的两种方式在语义上都是相同的。我知道生成的 IL 可能不一样(没有检查过)。
考虑以下结构:
struct SomeWrapper
{
public Guid guid;
public static implicit operator SomeWrapper(Guid guid) => new SomeWrapper {guid = guid};
}
Run Code Online (Sandbox Code Playgroud)
这个结构定义了一个隐式运算符来处理Guidas SomeWrapper,非常简单。以下所有方法都可以编译,第一个除外PleaseDoNotCompile:
static Task<SomeWrapper> PleaseDoNotCompile() => Task.Run(() => Guid.NewGuid());
static Task<SomeWrapper> WhyDoYouCompile() => Task.Run(() =>
{
return Guid.NewGuid();
return new SomeWrapper();
});
static SomeWrapper IUnderstandWhyYouCompile() => Guid.NewGuid();
static async Task<SomeWrapper> IUnderstandWhyYouCompileToo() => await Task.Run(() => Guid.NewGuid());
Run Code Online (Sandbox Code Playgroud)
特别是,WhyDoYouCompile只是第一个带有返回SomeWrapper值的附加 return 语句的方法。很明显,返回是无法访问的代码。它仍然编译,而第一个没有。
因此,除了附加的 return 语句之外,这两种方法之间实际上还有另一个区别:PleaseDoNotCompileuses Task.Run<Guid>(Func<Guid> function)While WhyDoYouCompileuses Task.Run<SomeWrapper>(Func<SomeWrapper> function) …