2012-02-13 2 views
37

Одной из особенностей Паскаля я нашел очень полезным была возможность назвать тип данных, напримерОпределение псевдонимов типа

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

var 
me: person; 
you: person; 

etc 

Можете ли вы сделать что-то подобное в C#? Я хочу быть в состоянии сделать что-то вроде

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

complexList peopleList; 
anotherList otherList; 

Так что, если я должен изменить определение типа данных, я могу сделать это в одном месте.

Поддерживает ли C# способ достичь этого?

+6

«' using' псевдоним»в C# есть в файле только –

+0

Вот еще один вопрос, связанный с этим: http://stackoverflow.com/questions/161477/ эквивалент-typedef-in-c-sharp – Candide

ответ

31

Это не значит, что вы делаете в Паскале, но можете использовать using -directive. Посмотрите здесь на how to use it

Пример:

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(); 
     } 
    } 
} 
+13

второстепенная точка: 'использование' в верхней части файла ** директивы * *, а не ** заявления **; «использование заявления» - это вещь, связанная с 'IDisposable'. В частности, это «использование псевдонима». –

+2

Примечание. Также, если вы просто называете класс «MyList», директива по использованию, конечно, больше не требуется (и это также решает исходную проблему). – BrainSlugs83

+0

Ссылка указывает на старую страницу документации. Хотя он все еще активен и точен (и имеет ссылку ниже), здесь ссылка на новую страницу должна удаляться по старой странице. https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive – MadCityDev

45

Да, это возможно. Вы можете написать:

using System; 
using System.Collections.Generic; 

namespace ConsoleApplication12 
{ 
    using MyAlias = List<Tuple<int, string, int>>; 
} 

или, если они будут объявлены вне пространства имен:

using System; 
using System.Collections.Generic; 

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

namespace ConsoleApplication12 
{ 
} 

затем использовать его в качестве типа:

MyAlias test = new MyAlias(); 
+1

Вы пробовали это? он не будет компилироваться (при условии, что 'List ' является типичным); псевдоним 'using' всегда требует указания полного пространства имен. –

+1

@MarcGravell Конечно, я тестировал его, он определенно компилируется и отлично работает. – ken2k

+1

@MarcGravell Precision: он отлично работает, если он объявлен в области пространства имен. Обновление ответа. – ken2k

3

Да, вы можете сделать это, однако вам нужно для определения полных типов, то есть определение будет следующим:

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

Это указано для каждого файла, так же как и директивы using для пространств имен.

nitpick: Обычно тип .NET является PascalCased.

+0

«Полные типы» не требуются. Если используется другое 'using' (например,' using System.Collections.Generic; ', то« полные типы »не нужны. – ken2k

+1

@ ken2k некорректно; псевдоним 'using' всегда требует, чтобы он явно определялся пространством имен **, даже если ** существующие директивы' use' принесли бы его в область видимости; значение: 'using var list = List ;' is ** not ** valid, даже после 'using System.Collections.Generic;' –

+0

Это не требуется, если на самом деле псевдоним определен внутри области пространства имен. – ken2k

12

Что относительно наследства?

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

var complexList = new ComplexList(); 

Это похоже на аналогичную концепцию (с преимуществами).

+3

За исключением использования наследования не удастся во всех случаях, когда тип, к которому относится псевдоним, запечатан. –

+6

Однако, если вы сделаете это так и объявите метод 'void Foo (ComplexList a)', назвав его как 'Foo (новый List >();' будет ошибкой типа, несмотря на то, что типы изоморфны. – cemper93

14

Вы можете создать тип:

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

Это не совсем такой же, как псевдоним, но в большинстве случаев, вы не должны видеть каких-либо различий.

+0

. Интересный подход. Спасибо. – haughtonomous

+2

. Первым ответом будет хорошая идея ;-) –

+0

@ Serge-appTranslator, если это не то же самое, что мой ответ, но через 2 минуты. – Jodrell

4

Из синтаксиса, показанного на первоначальный вопрос, это выглядит, как вы на самом деле просто спрашивают, как сделать класс в C#, а не так, как псевдоним тип.

Если вы хотите, чтобы более простое имя было напечатано, чем List<Tuple<int,string,int>>, и вы хотите, чтобы оно было «глобальным» (т. Е. Не для файла), я бы создал новый класс, унаследовавший упомянутый класс, и не объявлял никаких дополнительных членов. Например:

public class MyTrinaryTupleList: List<Tuple<int,string,int>> { } 

Это дает одно единственное место управления и не требует дополнительных инструкций.

Однако я хотел бы также сделать шаг дальше, и предприятие, вероятно, вы не хотите кортеж, а другой класс, например:

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; 
    } 
} 

а затем список вашего типа вы можете выполните следующие действия:

public class PersonList: List<Person> { } 

Кроме того, если вам нужен другой список конкретных вспомогательных свойств или методов, которые вы можете добавить их к классу PersonList, а также.

0

Просто простой, используя бы:

using Foo = System.UInt16; 

public class Test { 
    public Foo Bar { get;set; } 
} 
Смежные вопросы