C#定义一个元组作为类型

问题描述 投票:0回答:3

在 C# 中有没有办法定义一个包含元组的自定义类型? 例如:

Type MyParams Tuple<string, string>
?

动机:我在父类中有以下功能:

protected virtual IEnumerable<(string, string)> GetConfigs()

这将被每个子类覆盖。我正在寻找一种方法将该元组定义为类型以将返回类型声明为

IEnumerable<Params>
而不是复制元组。

c# types tuples
3个回答
6
投票
  • 创建一个 record,它是一个引用 (C# 9+) 或值类型 (C# 10+),它是不可变的,并且在这两种情况下的行为都像值类型。 C# 记录是具有由编译器自动添加的功能的类或结构。另请参阅记录(C# 参考)使用记录类型 - C# 教程 |微软学习.
  • 创建一个struct,它是一个值类型。
  • 或声明:
    global using MyParams = System.ValueTuple<string, string>;
    
    从 C#12 开始,您可以为任何类型创建别名,即也可以为 ValueTuples 创建别名:
    global using MyParams = (string key , string value);
    

这个全局使用必须先于文件中的任何其他

using
。 C# 12 之前的版本不允许使用 C# 元组语法
(string a, string b)
创建别名。因此,您必须使用
t.Item1
t.Item2
等访问元组元素

如果省略

global
关键字(C#10+),则指令的范围仅限于当前文件。

现在您可以将方法声明为

protected virtual IEnumerable<MyParams> GetConfigs()
{
   ...
}

注意;但是,这种全局使用仅在当前程序集中已知!

因此,它在类库的公共API中的使用受到限制。

仍然可以使用这种类型访问该库的成员,所以。

在一个程序集中有这个声明

global using MyParams = System.ValueTuple<string, string>;

namespace MyLibrary;

public class Class1
{
    public MyParams p = ("hello", "world");
}

您可以在引用第一个的另一个程序集中编写它:

var obj = new MyLibrary.Class1();
Console.WriteLine(obj.p);

但是像

MyLibrary.MyParams p;
这样的声明在另一个组件中是不可能的。


4
投票

你要找的是 alias using directive。但是,根据文档,您可以从 C# 10 开始使用全局范围定义它。否则,当您要使用它时,您需要在每个文件中创建一个别名。

using MyParams = System.Tuple<string, string>;

用法:

var foo = new MyParams("foo", "baz");

3
投票

首先,我肯定会推荐有一个适当定义的类型,因为它是针对 API 的(尽管公平地说,我无论如何都不喜欢元组)。像这样的事情可能会做,类型转换到/从(字符串,字符串):

public struct SuitableTypeName
{
    public string SomeName;
    public string SomeDifferentName;

    public SuitableTypeName(string someName, string someDifferentName)
    {
        SomeName = someName;
        SomeDifferentName = someDifferentName;
    }

    public static implicit operator (string, string)(SuitableTypeName name)
    {
        return (name.SomeName, name.SomeDifferentName);
    }

    public static explicit operator SuitableTypeName ((string, string) tuple)
    {
        return new SuitableTypeName(tuple.Item1, tuple.Item2);
    }
}

请注意,您可能会考虑使用类而不是结构。在此示例中,它是一个可变结构,可能会导致混淆/意外行为,因此如果您担心这一点,您也可以将其设为不可变。此外,出于某种原因,一些团队对可变结构有非常强烈的感觉,所以如果你在一个团队中工作并决定按原样使用它,你可能需要检查你的编码标准或与其他人一起清除它。

© www.soinside.com 2019 - 2024. All rights reserved.