定义类型别名

hau*_*ous 64 c# types

Pascal的一个特性我发现非常有用的是命名数据类型的能力,例如

type
 person: record
             name: string;
             age: int;
         end;

var
 me: person;
 you: person;

etc
Run Code Online (Sandbox Code Playgroud)

你能用C#做类似的事吗?我希望能够做类似的事情

using complexList = List<Tuple<int,string,int>>;

complexList peopleList;
anotherList otherList;
Run Code Online (Sandbox Code Playgroud)

因此,如果我必须更改数据类型的定义,我可以在一个地方完成.

C#是否支持实现此目的的方法?

ken*_*n2k 73

是的,这是可能的.你可以写:

using System;
using System.Collections.Generic;

namespace ConsoleApplication12
{
    using MyAlias = List<Tuple<int, string, int>>;
}
Run Code Online (Sandbox Code Playgroud)

或者,如果在命名空间外声明:

using System;
using System.Collections.Generic;

using MyAlias = System.Collections.Generic.List<System.Tuple<int, string, int>>;

namespace ConsoleApplication12
{
}
Run Code Online (Sandbox Code Playgroud)

然后将其用作类型:

MyAlias test = new MyAlias();
Run Code Online (Sandbox Code Playgroud)

  • 为什么这不是公认的答案?这实际上提供了问题的解决方案 (7认同)
  • @ ken2k你可以导出MyAlias并在其他源文件中使用它吗?你是怎样做的? (5认同)
  • 你试过这个吗?它不会编译(假设 `List&lt;T&gt;` 是典型的);“using”别名始终需要指定完整的命名空间。 (2认同)
  • @MarcGravell 当然,我测试了它,它肯定可以编译并且工作正常。 (2认同)
  • @Jodrell我很少在`namespace`中看到`using`指令,主要是因为这不是大多数工具放置它们的地方. (2认同)

Mit*_*dir 60

你在Pascal中做的并不是很令人兴奋,但你可以使用using-directive.看看如何使用它

例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyList = Dummy2.CompleXList;

namespace Dummy2
{
    public class Person 
    {
    }

    public class CompleXList : List<Person> 
    { 
    }


    class Program
    {
        static void Main(string[] args)
        {
            MyList l1 = new MyList();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 小点:文件顶部的`using`是**指令**,而不是**语句**; "using statement"是涉及`IDisposable`的东西.特别是,这是一个"使用别名". (23认同)
  • 值得注意的是:如果你只是将类命名为"MyList",那么当然不再需要using指令(这也解决了原始问题). (2认同)
  • 这是否适用于命名元组?我不能让它工作。我尝试的是:`使用 MyType = (TypeA a, TypeB b);`。我想我可以使用未命名的元组,它会起作用,但我真的想要名称而不是`Item1`、`Item2`。:( (2认同)

Ser*_*ier 21

您可以创建一个类型:

class ComplexList : List<Tuple<int,string,int>> { }
Run Code Online (Sandbox Code Playgroud)

这与别名不完全相同,但在大多数情况下,您不应该看到任何差异.

  • 但是,如果类型是密封的,那么这不起作用(例如,你试图"别名"`KeyValuePair <K,V>`) (5认同)
  • 提出我的答案将是一个好主意;-) (3认同)
  • 由于子类化,这也可能无法通过相等性检查。子类化 != 别名。 (3认同)
  • @jodrell:哎哟!我想我们正在同时输入它.你刚赢得比赛条件.顺便说一下,你的答案非常好:我赞成它;-) (2认同)
  • 这很有用,但有其局限性,例如您不能将 ComplexList 分配给返回 List&lt;Tuple&lt;int,string,int&gt;&gt; 的函数的结果,并且您不能传递 List&lt;Tuple&lt;int,string,int &gt;&gt; 转换为带有 ComplexList 参数的函数。 (2认同)

Jod*_*ell 16

继承怎么样?

class ComplexList : List<Tuple<int, string, int>> {}

var complexList = new ComplexList();
Run Code Online (Sandbox Code Playgroud)

这似乎是一个类似的概念,但在C#中没有直接等效的基于类型的别名,只有名称空间别名.

如果要避免在代码中出现类型名称冲突,可以使用命名空间别名.

如果要创建一个"是"另一种类型的实例的新类型,继承是一种选择.

  • 但是,如果你这样做并声明一个`void Foo(ComplexList a)`方法,将其称为`Foo(new List <Tuple <int,string,int >>();`将是一个类型错误,尽管类型是同构的. (7认同)
  • 除了使用继承之外,在别名引用的类型被密封的所有情况下都将失败. (5认同)

Bra*_*s83 6

从初始问题中显示的语法来看,看起来你真的只是在询问如何在C#中创建一个类,而不是如何为一个类型设置别名.

如果你想要一个更简单的名字输入List<Tuple<int,string,int>>,并且你希望它是"全局的"(即不是每个文件),我会创建一个继承所述类并且没有声明其他成员的新类.像这样:

public class MyTrinaryTupleList: List<Tuple<int,string,int>> { }
Run Code Online (Sandbox Code Playgroud)

这给了一个单独的管理位置,而不需要额外的使用语句.

但是,我还会更进一步,冒险你可能不想要一个元组,而是另一个类,例如:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public int FavoriteNumber { get; set; }

    public Person() { }

    public Person(string name, int age, int favoriteNumber) 
    { 
        this.Name = name; 
        this.Age = age; 
        this.FavoriteNumber = favoriteNumber; 
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,对于列表类型,您可以执行以下操作:

public class PersonList: List<Person> { }
Run Code Online (Sandbox Code Playgroud)

此外,如果您需要其他列表特定的辅助属性或方法,您也可以将它们添加到PersonList类.


flq*_*flq 5

是的,您可以这样做,但是您需要指定完整类型,即定义变为:

using ComplexList = System.Collections.Generic.List<System.Tuple<int,string,int>>;
Run Code Online (Sandbox Code Playgroud)

这是按文件指定的,很像命名空间的 using 指令。

挑剔:通常,.NET 中的类型是 PascalCased。

  • @ken2k 不正确;`using` 别名总是要求它显式地被命名空间限定,**即使**现有的 `using` 指令会将它带入范围;意思是:`using var list = List&lt;int&gt;;` **not** 有效,即使在 `using System.Collections.Generic;` 之后 (2认同)