5

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.

HudsonGraeme
  • 399
  • 3
  • 10
  • To clarify, as I'm not a Swift guy, does the code Swift code above actually create a type, as opposed to aliasing an existing type? – ProgrammingLlama Oct 22 '18 at 01:38
  • Apologies, I should reword my question; `typealias` does not create any new type, it simply provide a new name for a type or an arrangement of types. – HudsonGraeme Oct 22 '18 at 01:46
  • Can you explain this: "an arrangement of types"? – ProgrammingLlama Oct 22 '18 at 01:46
  • 1
    You may find the answers to this (close, but not quite duplicate) question useful https://stackoverflow.com/questions/9257989/defining-type-aliases – Ryan Leach Oct 22 '18 at 01:48
  • @John I wasn't sure what to call it; I was referring to `typealias`'s like the ones in the question where there are multiple types assigned to one alias, for example the first `typealias` in the question contains a string and a bool value which are in order; hence the `typealias` `Answer` is actually two types. Again apologies for my lack of clarity; [click here for a professional definition](https://www.programiz.com/swift-programming/typealias) – HudsonGraeme Oct 22 '18 at 02:00
  • @RyanTheLeach I was looking at that one for quite some time but wasn't able to make it work for me – HudsonGraeme Oct 22 '18 at 02:01
  • I ended up using XML and a custom button class to accomplish this: [source code here](https://github.com/HudsonGraeme/Qomputers/) – HudsonGraeme Oct 23 '18 at 18:15

4 Answers4

5

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.

heshuimu
  • 144
  • 1
  • 10
2

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.

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
Sean
  • 1,359
  • 11
  • 15
  • 3
    FYI That's not _all_ `using` does in different contexts. I rather think OP meant they were trying something like `using ABC = String;` (which is entirely valid C# and will create an alias of `String` called `ABC`). – ProgrammingLlama Oct 22 '18 at 01:36
1

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.

vinicius.ras
  • 1,516
  • 3
  • 14
  • 28
  • I'm not sure it is, it can't be returned from methods readily. – Ryan Leach Oct 22 '18 at 02:38
  • Anonymously-typed objects could be returned by using the `dynamic` return-type in order to have access to its members. Downside is that this completely disables compilation-time type checking, which may throw runtime exceptions if one ever tries to access an non-existing member of the returned object. – vinicius.ras Oct 22 '18 at 02:46
1

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;}
}
ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
  • @Spencer No worries :) I think the accepted answer is the more useful one, for now at least. I just wanted to add this for completeness. – ProgrammingLlama Oct 22 '18 at 03:46