是否有一种方法可以使用Tuple类,但在其中提供项目的名称?

例如:

public Tuple<int, int, int int> GetOrderRelatedIds()

它返回OrderGroupId、OrderTypeId、OrderSubTypeId和OrderRequirementId的id。

让我的方法的用户知道哪个是哪个就好了。(当您调用该方法时,结果为result。Item1,结果。第二条,结果。Item3 result.Item4。不清楚哪个是哪个。)

(我知道我可以创建一个类来保存所有这些id,但这些id已经有自己的类,它们生活在其中,为这个方法的返回值创建一个类似乎很愚蠢。)


当前回答

只是补充一下@MichaelMocko的答案。元组目前有几个陷阱:

你不能在EF表达式树中使用它们

例子:

public static (string name, string surname) GetPersonName(this PersonContext ctx, int id)
{
    return ctx.Persons
        .Where(person => person.Id == id)
        // Selecting as Tuple
        .Select(person => (person.Name, person.Surname))
        .First();
}

这将导致编译失败,出现“表达式树可能不包含元组文字”错误。不幸的是,表达式树API在向语言中添加元组时并没有扩展对元组的支持。

跟踪(并投票)这个问题的更新:https://github.com/dotnet/roslyn/issues/12897

为了解决这个问题,你可以先将其转换为匿名类型,然后将值转换为元组:

// Will work
public static (string name, string surname) GetPersonName(this PersonContext ctx, int id)
{
    return ctx.Persons
        .Where(person => person.Id == id)
        .Select(person => new { person.Name, person.Surname })
        .ToList()
        .Select(person => (person.Name, person.Surname))
        .First();
}

另一种选择是使用ValueTuple。创建:

// Will work
public static (string name, string surname) GetPersonName(this PersonContext ctx, int id)
{
    return ctx.Persons
        .Where(person => person.Id == id)
        .Select(person => ValueTuple.Create(person.Name, person.Surname))
        .First();
}

引用:

https://www.damirscorner.com/blog/posts/20181207-NoSupportForTuplesInExpressionTrees.html 将匿名类型转换为新的c# 7元组类型

你不能用lambda解构它们

有一个增加支持的提议:https://github.com/dotnet/csharplang/issues/258

例子:

public static IQueryable<(string name, string surname)> GetPersonName(this PersonContext ctx, int id)
{
    return ctx.Persons
        .Where(person => person.Id == id)
        .Select(person => ValueTuple.Create(person.Name, person.Surname));
}

// This won't work
ctx.GetPersonName(id).Select((name, surname) => { return name + surname; })

// But this will
ctx.GetPersonName(id).Select(t => { return t.name + t.surname; })

引用:

c# 7元组和lambda

它们不会很好地连载

using System;
using Newtonsoft.Json;

public class Program
{
    public static void Main() {
        var me = (age: 21, favoriteFood: "Custard");
        string json = JsonConvert.SerializeObject(me);

        // Will output {"Item1":21,"Item2":"Custard"}
        Console.WriteLine(json); 
    }
}

元组字段名仅在编译时可用,并在运行时完全删除。

引用:

使值元组属性名在运行时可解析 c# 7元组支持(Newtonsoft.Json)

其他回答

我会把商品名称写在汇总单上。 因此,通过将鼠标悬停在helloworld()函数上,文本将显示hello = Item1和world = Item2

 helloworld("Hi1,Hi2");

/// <summary>
/// Return hello = Item1 and world Item2
/// </summary>
/// <param name="input">string to split</param>
/// <returns></returns>
private static Tuple<bool, bool> helloworld(string input)
{
    bool hello = false;
    bool world = false;
    foreach (var hw in input.Split(','))
    {
        switch (hw)
        {
            case "Hi1":
                hello= true;
                break;
            case "Hi2":
                world= true;
                break;
        }

    }
    return new Tuple<bool, bool>(hello, world);
}

只是补充一下@MichaelMocko的答案。元组目前有几个陷阱:

你不能在EF表达式树中使用它们

例子:

public static (string name, string surname) GetPersonName(this PersonContext ctx, int id)
{
    return ctx.Persons
        .Where(person => person.Id == id)
        // Selecting as Tuple
        .Select(person => (person.Name, person.Surname))
        .First();
}

这将导致编译失败,出现“表达式树可能不包含元组文字”错误。不幸的是,表达式树API在向语言中添加元组时并没有扩展对元组的支持。

跟踪(并投票)这个问题的更新:https://github.com/dotnet/roslyn/issues/12897

为了解决这个问题,你可以先将其转换为匿名类型,然后将值转换为元组:

// Will work
public static (string name, string surname) GetPersonName(this PersonContext ctx, int id)
{
    return ctx.Persons
        .Where(person => person.Id == id)
        .Select(person => new { person.Name, person.Surname })
        .ToList()
        .Select(person => (person.Name, person.Surname))
        .First();
}

另一种选择是使用ValueTuple。创建:

// Will work
public static (string name, string surname) GetPersonName(this PersonContext ctx, int id)
{
    return ctx.Persons
        .Where(person => person.Id == id)
        .Select(person => ValueTuple.Create(person.Name, person.Surname))
        .First();
}

引用:

https://www.damirscorner.com/blog/posts/20181207-NoSupportForTuplesInExpressionTrees.html 将匿名类型转换为新的c# 7元组类型

你不能用lambda解构它们

有一个增加支持的提议:https://github.com/dotnet/csharplang/issues/258

例子:

public static IQueryable<(string name, string surname)> GetPersonName(this PersonContext ctx, int id)
{
    return ctx.Persons
        .Where(person => person.Id == id)
        .Select(person => ValueTuple.Create(person.Name, person.Surname));
}

// This won't work
ctx.GetPersonName(id).Select((name, surname) => { return name + surname; })

// But this will
ctx.GetPersonName(id).Select(t => { return t.name + t.surname; })

引用:

c# 7元组和lambda

它们不会很好地连载

using System;
using Newtonsoft.Json;

public class Program
{
    public static void Main() {
        var me = (age: 21, favoriteFood: "Custard");
        string json = JsonConvert.SerializeObject(me);

        // Will output {"Item1":21,"Item2":"Custard"}
        Console.WriteLine(json); 
    }
}

元组字段名仅在编译时可用,并在运行时完全删除。

引用:

使值元组属性名在运行时可解析 c# 7元组支持(Newtonsoft.Json)

直到c# 7.0,除了定义自己的类型,还没有办法做到这一点。

在c# 7.0 (Visual Studio 2017)中,有一个新的结构可以做到这一点:

(string first, string middle, string last) LookupName(long id)

我想我会创建一个类,但另一种选择是输出参数。

public void GetOrderRelatedIds(out int OrderGroupId, out int OrderTypeId, out int OrderSubTypeId, out int OrderRequirementId)

因为你的元组只包含整数,你可以用Dictionary<string,int>来表示它

var orderIds = new Dictionary<string, int> {
    {"OrderGroupId", 1},
    {"OrderTypeId", 2},
    {"OrderSubTypeId", 3},
    {"OrderRequirementId", 4}.
};

但我也不建议这样做。