在赋值的左侧使用空条件运算符
Using the null-conditional operator on the left-hand side of an assignment
我有几个页面,每个页面都有一个名为 Data
的 属性。在另一页上,我将此数据设置为:
if (MyPage1 != null)
MyPage1.Data = this.data;
if (MyPage2 != null)
MyPage2.Data = this.data;
if (MyPage3 != null)
MyPage3.Data = this.data;
是否可以在 MyPage
上使用空条件运算符?我在想这样的事情:
MyPage?.Data = this.data;
但是当我这样写的时候,出现如下错误:
The left-hand side of an assignment must be a variable, property or indexer.
我知道这是因为 MyPage
可能为空,左侧不再是变量。
并不是说我不能像已经拥有它那样使用它,而是我只是想知道是否有可能对此使用 null 条件运算符。
空传播运算符 returns 一个值。并且由于您必须在赋值的左侧有一个变量,而不是一个值,所以您不能以这种方式使用它。
当然,您可以使用三元运算符来缩短内容,但另一方面,这并不能真正提高可读性。
Joachim Isaksson 对您的问题的评论显示了一种应该有效的不同方法。
试试这个
将所有页面添加到 myPageList。
IEnumerable<MyPage> myPageList;
foreach(MyPage myPage in myPageList)
{
if (myPage != null)
myPage.Data = this.data;
}
正如 Joachim Isaksson 在评论中建议的那样,我现在有一个方法 SetData(Data data)
并像这样使用它:
MyPage1?.SetData(this.data);
MyPage2?.SetData(this.data);
MyPage3?.SetData(this.data);
通用的 SetValue 扩展方法(但仅适用于 ref 属性)是:
public static void SetValue<T>(this T property, T value)
{
property = value;
}
并且会像
一样使用
ButtonOrNull?.Visibility.SetValue(Visibility.Hidden);
我想到了以下扩展,
public static class ObjectExtensions
{
public static void SetValue<TValue>(this object @object, string propertyName, TValue value)
{
var property = @object.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
if (property?.CanWrite == true)
property.SetValue(@object, value, null);
}
}
可以全局调用;这仅适用于 public 个属性。
myObject?.SetValue("MyProperty", new SomeObject());
以下改进版本适用于任何东西,
public static void SetValue<TObject>(this TObject @object, Action<TObject> assignment)
{
assignment(@object);
}
也可以全局调用,
myObject?.SetValue(i => i.MyProperty = new SomeObject());
但是扩展名称有些误导,因为 Action
并不完全需要赋值。
派对来晚了,但我是带着类似的问题来到这篇文章的。我采用了 SetValue 方法的想法并创建了一个通用扩展方法,如下所示:
/// <summary>
/// Similar to save navigation operator, but for assignment. Useful for += and -= event handlers.
/// If <paramref name="obj"/> is null, then <paramref name="action"/> is not performed and false is returned.
/// If <paramref name="obj"/> is not null, then <paramref name="action"/> is performed and true is returned.
/// </summary>
public static bool SafeAssign<T>(this T obj , Action<T> action ) where T : class
{
if (obj is null) return false;
action.Invoke(obj);
return true;
}
示例用法,用于附加和分离事件处理程序:
public void Attach() => _control.SafeAssign(c => c.MouseDown += Drag);
public void Detach() => _control.SafeAssign(c => c.MouseDown-= Drag);
希望有人觉得它有用:)
您可以使用扩展方法
public static void NCC<T>(this T instance, System.Action<T> func)
where T : class
{
if (instance != null)
{
func(instance);
}
}
MyPage1.NCC(_=>_.Data = this.data);
我有几个页面,每个页面都有一个名为 Data
的 属性。在另一页上,我将此数据设置为:
if (MyPage1 != null)
MyPage1.Data = this.data;
if (MyPage2 != null)
MyPage2.Data = this.data;
if (MyPage3 != null)
MyPage3.Data = this.data;
是否可以在 MyPage
上使用空条件运算符?我在想这样的事情:
MyPage?.Data = this.data;
但是当我这样写的时候,出现如下错误:
The left-hand side of an assignment must be a variable, property or indexer.
我知道这是因为 MyPage
可能为空,左侧不再是变量。
并不是说我不能像已经拥有它那样使用它,而是我只是想知道是否有可能对此使用 null 条件运算符。
空传播运算符 returns 一个值。并且由于您必须在赋值的左侧有一个变量,而不是一个值,所以您不能以这种方式使用它。
当然,您可以使用三元运算符来缩短内容,但另一方面,这并不能真正提高可读性。
Joachim Isaksson 对您的问题的评论显示了一种应该有效的不同方法。
试试这个 将所有页面添加到 myPageList。
IEnumerable<MyPage> myPageList;
foreach(MyPage myPage in myPageList)
{
if (myPage != null)
myPage.Data = this.data;
}
正如 Joachim Isaksson 在评论中建议的那样,我现在有一个方法 SetData(Data data)
并像这样使用它:
MyPage1?.SetData(this.data);
MyPage2?.SetData(this.data);
MyPage3?.SetData(this.data);
通用的 SetValue 扩展方法(但仅适用于 ref 属性)是:
public static void SetValue<T>(this T property, T value)
{
property = value;
}
并且会像
一样使用ButtonOrNull?.Visibility.SetValue(Visibility.Hidden);
我想到了以下扩展,
public static class ObjectExtensions
{
public static void SetValue<TValue>(this object @object, string propertyName, TValue value)
{
var property = @object.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
if (property?.CanWrite == true)
property.SetValue(@object, value, null);
}
}
可以全局调用;这仅适用于 public 个属性。
myObject?.SetValue("MyProperty", new SomeObject());
以下改进版本适用于任何东西,
public static void SetValue<TObject>(this TObject @object, Action<TObject> assignment)
{
assignment(@object);
}
也可以全局调用,
myObject?.SetValue(i => i.MyProperty = new SomeObject());
但是扩展名称有些误导,因为 Action
并不完全需要赋值。
派对来晚了,但我是带着类似的问题来到这篇文章的。我采用了 SetValue 方法的想法并创建了一个通用扩展方法,如下所示:
/// <summary>
/// Similar to save navigation operator, but for assignment. Useful for += and -= event handlers.
/// If <paramref name="obj"/> is null, then <paramref name="action"/> is not performed and false is returned.
/// If <paramref name="obj"/> is not null, then <paramref name="action"/> is performed and true is returned.
/// </summary>
public static bool SafeAssign<T>(this T obj , Action<T> action ) where T : class
{
if (obj is null) return false;
action.Invoke(obj);
return true;
}
示例用法,用于附加和分离事件处理程序:
public void Attach() => _control.SafeAssign(c => c.MouseDown += Drag);
public void Detach() => _control.SafeAssign(c => c.MouseDown-= Drag);
希望有人觉得它有用:)
您可以使用扩展方法
public static void NCC<T>(this T instance, System.Action<T> func)
where T : class
{
if (instance != null)
{
func(instance);
}
}
MyPage1.NCC(_=>_.Data = this.data);