【问题标题】:Can I initialize an object with a function returning a ValueTuple?我可以使用返回 ValueTuple 的函数初始化对象吗?
【发布时间】:2019-01-24 13:09:55
【问题描述】:

我想用这样的 ValueTuple 初始化一个对象:

var m = new SearchResultViewModel
{
     (Elements, SomeNumber) = this.SearchResultItems()
};

private (List<string> a, int b) SearchResultItems()
{
    [...]
    return (list, 1024);
}

在哪里

public class SearchResultViewModel
{
    public IList<string> Elements { get; set; }

    public long SomeNumber { get; set; }
}

这样的(或类似的)可能吗?编译器给了我一堆错误: 无法使用集合初始化程序初始化类型“SearchResultViewModel”,因为它没有实现“System.Collections.IEnumerable”, 初始化器成员声明器无效, 当前上下文中不存在名称“元素”, 当前上下文中不存在名称“SomeNumber”,

虽然这段代码可以正常工作:

var m = new SearchResultViewModel();
(m.Elements, m.SomeNumber) = this.SearchResultItems();

这也可以编译(但我不想调用该函数两次):

var m = new SearchResultViewModel()
{
   Elements = this.SearchResultItems().Item1,
   SomeNumber = this.SearchResultItems().Item2
};

【问题讨论】:

  • 不可能,您需要在 ViewModel 中创建 ValueTuple 单个属性
  • 非常感谢您,MistyK。

标签: c# c#-7.0


【解决方案1】:

如果你真的想做类似的事情,你可以使用转换运算符。

public class SearchResultViewModel
  {
    public IList<string> Elements { get; set; }
    public long SomeNumber { get; set; }

    public static explicit operator SearchResultViewModel((List<string> elements, int someNumber) tuple)
    {
      return new SearchResultViewModel()
      {
        Elements = tuple.elements,
        SomeNumber = tuple.someNumber
      };
    }
  }

现在可以执行以下操作:

var m = SearchResultItems() as SearchResultViewModel;

虽然这个解决方案有效,但我个人不是粉丝。以这种方式投射 ValueTuple 似乎是错误的。但这是我的看法。

【讨论】:

  • 为什么要使用显式运算符而不是构造函数?
  • 我规定只制作真正必要的构造函数。示例:如果一个类有一些必填字段,请将它们放在构造函数中以使其清楚。我从不创建构造函数来匹配类之外的方法的特定结果(如 OP 的示例方法)。因此,我没有想到使用构造函数的可能性。但你是对的,它也会起作用。在我看来,SearchResultItems() 应该已经返回一个 SearchResultViewModel。如果您有一个包含数据的类,为什么不将它用作方法的结果,如果可能的话。
猜你喜欢
  • 1970-01-01
  • 2014-11-03
  • 2019-12-01
  • 2011-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-09
  • 1970-01-01
相关资源
最近更新 更多