【问题标题】:C# Equivalent of Swift typealiasSwift 类型别名的 C# 等效项
【发布时间】:2019-03-26 01:12:58
【问题描述】:

我是 C# 新手,习惯了 Swift,所以请多多包涵。

我想完全按照下面的 Swift 代码描述的方式在 C# 中使用类型:

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

再举个例子,现在使用上面的typealias's 在 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 代码实际上是创建一个类型,而不是为现有类型设置别名吗?
  • 抱歉,我应该改写我的问题; typealias 不会创建任何新类型,它只是为类型或类型排列提供新名称。
  • 你能解释一下:“类型的排列”吗?
  • 您可能会发现这个(接近但不完全重复)问题的答案很有用stackoverflow.com/questions/9257989/defining-type-aliases
  • @John 我不知道该怎么称呼它;我指的是typealias,就像问题中的那样,其中有多种类型分配给一个别名,例如问题中的第一个typealias包含一个字符串和一个布尔值,它们是有序的;因此 typealias Answer 实际上是两种类型。再次为我的不明确表示歉意; click here for a professional definition

标签: c# swift types


【解决方案1】:

这个线程很旧,但我想添加一个简单的答案,因为现有的都不是。

C# 没有与typealias 完全等价的:

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

  • using 定义仅保留在定义它的文件中。它不能用于项目的其他部分。

【讨论】:

    【解决方案2】:

    如果我没有误会,您需要类似于别名 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 issue

    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 不用担心 :) 我认为接受的答案是更有用的答案,至少目前如此。为了完整起见,我只是想添加它。
    【解决方案3】:

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

    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

    【讨论】:

    • 我不确定,它不能轻易地从方法中返回。
    • 匿名类型的对象可以使用dynamic返回类型返回,以便访问其成员。缺点是这完全禁用了编译时类型检查,如果有人试图访问返回对象的不存在成员,这可能会引发运行时异常。
    【解决方案4】:

    对于引用类型,我会使用 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 语句与一次性对象一起使用,以确保资源被释放。

    【讨论】:

    • 仅供参考,这不是 all using 在不同情况下所做的。我宁愿认为 OP 意味着他们正在尝试类似 using ABC = String; 的东西(这是完全有效的 C# 并将创建一个名为 String 的别名 ABC)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-30
    • 2015-03-04
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    • 2014-08-15
    相关资源
    最近更新 更多