在 C# 中有没有办法定义一个包含元组的自定义类型? 例如:
Type MyParams Tuple<string, string>
?
动机:我在父类中有以下功能:
protected virtual IEnumerable<(string, string)> GetConfigs()
这将被每个子类覆盖。我正在寻找一种方法将该元组定义为类型以将返回类型声明为
IEnumerable<Params>
而不是复制元组。
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;
这样的声明在另一个组件中是不可能的。
你要找的是 alias using directive。但是,根据文档,您可以从 C# 10 开始使用全局范围定义它。否则,当您要使用它时,您需要在每个文件中创建一个别名。
using MyParams = System.Tuple<string, string>;
用法:
var foo = new MyParams("foo", "baz");
首先,我肯定会推荐有一个适当定义的类型,因为它是针对 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);
}
}
请注意,您可能会考虑使用类而不是结构。在此示例中,它是一个可变结构,可能会导致混淆/意外行为,因此如果您担心这一点,您也可以将其设为不可变。此外,出于某种原因,一些团队对可变结构有非常强烈的感觉,所以如果你在一个团队中工作并决定按原样使用它,你可能需要检查你的编码标准或与其他人一起清除它。