C# Equivalent of Swift typealias

Viewed 3007

I'm new to C# and used to Swift, so please bear with me.

I would like to use types in C# exactly in the manner described by the Swift code below:

typealias Answer = (title: String, isCorrect: Bool)
typealias Question = (Question: String, Answers: [Answer])

For further example, it is now very simple to make a Question in swift using the above typealias's:

Question(Question: "What is this question?", Answers: [("A typedef", false), ("FooBar", false), ("I don't know", false), ("A Question!", true)])

I've tried using using statements and creating abstract classes to no avail so far.

Thanks in advance.

4 Answers

This thread is old but I would to add a straightforward answer as the none of the existing ones are.

C# does not have an exact equivalent to typealias:

  • The typealias definition in Swift is persistent and can be reused elsewhere.

  • The using definition only persists in the file where it is defined. It cannot be used in other parts of the project.

I would a class for reference types.

public class Answer
{
   public string Title {get;set;}
   public bool IsCorrect {get;set;}
}

or a struct for a value type

public struct Question
{
  public string Question;
  public Answer[] Answers;
}

Also, as an FYI the using statement is used with disposable objects to make sure the resources get released.

I've never worked with Swift, but seeing your example code, the closest think I can remember would be Anonymous Types. They allow you to structure a new object when declaring a variable and instantiating its object/value without having to declare a class/struct explicitly. Example:

var student = new
{
    Name = "John",
    LastName = "Doe",
    Age = 37,
    Hobbies = new [] { "Drinking", "Fishing", "Hiking" }
};

Then you can access the fields as student.LastName, student.Age, and so on. The types of properties inside the anonymous type are infered by the compiler (but you can use casts if you want to force specific types for some property).

Your example could be modelled something like that:

var answersArray = new[] {
    new { Title = "First answer", IsCorrect = false },
    new { Title = "Second answer", IsCorrect = true },
    new { Title = "Third answer", IsCorrect = false },
    new { Title = "Fourth answer", IsCorrect = false },
};
var questionData = new { Question = "To be or not to be?", Answers = answersArray };

And data would be accessed in some fashion like:

Console.WriteLine(questionData.Question);
foreach (var answer in answersArray)
    Console.WriteLine(answer.Title);

Problem with Anonymous Types is that the created objects are read only, so the values received by the properties of an anonymously-typed object cannot change after the object is instantiated.

The using keyword can be used for cases where you actually already have a defined class, and you wish to give an alias for that class, as in:

// The "HttpClient" class will now have an alias of "MyClient"
using MyClient = System.Net.Http.HttpClient;

This approach obviously requires the class you are aliasing to be previously defined, so I don't know if it fits your needs.

After these considerations, I'd say the best practice (and my advice) would really be to actually declare classes and/or structures in your code to represent the data you are using instead of trying to mimic Swift's typealias.

If I'm not misunderstanding, you want something akin to the ability to alias value tuples. Value tuples are a recent addition to C# and let you create objects (backed by ValueTuple<T,T,T,T>) without defining full classes. For example:

public (string Name, int Age) GetPerson()
{
    return (Name: "John", Age: 30);
}

var john = GetPerson();
Console.WriteLine(john.Age); // 30

At the moment, it's possible to alias types in C# (see below), but it isn't possible to do so with value tuples yet. There is an open GitHub issue for it.

using Abc = String;

Abc test = "hello";

In the meantime, it's probably best to create classes to represent your data (except in some situations where anonymous types are sufficient, see vinicius.ras's answer), e.g.:

public class Answer
{
    public string Title {get;set;}
    public bool IsCorrect {get;set;}
}

public class Question
{
    public string QuestionText {get;set;}
    public IList<Answer> Answers {get;set;}
}
Related