C#中与Swift的typealias相对应的是什么?

5

我是一个新手,之前用的是Swift,现在想学习C#,请多多关照。

我想要在C#中使用类型,就像下面Swift代码所描述的那样:

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

进一步举例来说,现在使用上述的typealias非常简单,可以轻松创建一个Swift中的Question
Question(Question: "What is this question?", Answers: [("A typedef", false), ("FooBar", false), ("I don't know", false), ("A Question!", true)])

我尝试过使用using语句和创建抽象类,目前都没有成功。

提前致谢。


澄清一下,由于我不是 Swift 的专家,上面的 Swift 代码实际上是创建了一个类型,而不是别名现有的类型吗? - ProgrammingLlama
你能解释一下“类型的排列”是什么意思吗? - ProgrammingLlama
1
您可能会发现这个(相似但不完全重复的)问题的答案很有用 https://dev59.com/w2ox5IYBdhLWcg3wWjHQ - Ryan Leach
@John 我不确定该怎么称呼它;我指的是像问题中的 typealias 一样有多个类型赋值给一个别名的情况,例如问题中的第一个 typealias 包含一个字符串和一个布尔值,它们按顺序排列;因此 typealias Answer 实际上是两种类型。再次为我的表述不清道歉;点击这里查看专业定义 - HudsonGraeme
@RyanTheLeach 我看了那个相当长的时间,但是没能让它对我起作用。 - HudsonGraeme
显示剩余2条评论
4个回答

5

此线程已经过时,但是我想添加一个直接的答案,因为现有的答案中没有一个是这样的。

C#没有与typealias完全等效的东西:

  • 在Swift中,typealias定义是持久的,可以在其他地方重复使用。

  • using定义只存在于定义它的文件中。它不能在项目的其他部分中使用。


2
我需要一个class作为参考类型。
public class Answer
{
   public string Title {get;set;}
   public bool IsCorrect {get;set;}
}

或者对于值类型,使用 struct
public struct Question
{
  public string Question;
  public Answer[] Answers;
}

另外,作为一条提示,using 语句用于可释放对象,以确保资源得到释放。

3
FYI,using在不同的上下文中所起的作用并不仅限于这些。我认为OP的意思是他们试图使用类似于using ABC = String;的语法(这是完全有效的C#语法,并将创建一个名为ABCString别名)。 - ProgrammingLlama

1

我从未使用过Swift,但看到你的示例代码后,我想到的最接近的是匿名类型。它们允许您在声明变量并实例化其对象/值时构造一个新对象,而无需显式声明类/结构。例如:

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

然后,你可以像这样访问字段:student.LastNamestudent.Age等。匿名类型中的属性类型由编译器推断(但如果您想强制某些属性具有特定类型,则可以使用强制转换)。
你的示例可以模拟成这样:
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 };

数据将以某种方式访问:

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

问题在于匿名类型创建的对象是只读的,因此在实例化对象后,无法更改匿名类型对象属性接收到的值。 using 关键字可用于已经定义类的情况下,你想要为该类指定别名的情况,例如:
// The "HttpClient" class will now have an alias of "MyClient"
using MyClient = System.Net.Http.HttpClient;

这种方法显然需要先定义您要别名的类,因此我不知道它是否符合您的需求。
经过这些考虑,我认为最佳实践(也是我的建议)实际上是在代码中声明类和/或结构来表示您正在使用的数据,而不是试图模仿Swift的typealias

我不确定它是否可以轻易地从方法中返回。 - Ryan Leach
可以使用 dynamic 返回类型返回匿名类型对象,以便访问其成员。缺点是这完全禁用了编译时类型检查,如果尝试访问返回对象的不存在成员,则可能会引发运行时异常。 - vinicius.ras

1
如果我没有误解,您想要类似于别名value tuples的功能。值元组是C#的最新添加,它允许您创建对象(由ValueTuple<T,T,T,T>支持),而无需定义完整的类。例如:
public (string Name, int Age) GetPerson()
{
    return (Name: "John", Age: 30);
}

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

目前,在C#中可以使用别名类型(请参见下文),但尚不能对值元组进行别名处理。有一个GitHub问题处于开放状态。

using Abc = String;

Abc test = "hello";

与此同时,最好创建类来表示您的数据(除了某些情况下匿名类型足以胜任,参见vinicius.ras的答案),例如:
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;}
}

@Spencer 不用担心 :) 我认为被接受的答案是更有用的,至少现在是这样。我只是想为了完整性而添加这个。 - ProgrammingLlama

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接