【问题标题】:Strong-typing for strings or other sealed classes字符串或其他密封类的强类型
【发布时间】:2012-03-26 18:02:12
【问题描述】:

我用通用术语来表述我的示例,因为它无需深入我的具体问题细节就可以理解重点。

假设您有一堆将字符串作为参数的方法。假设一个字符串是一个人的“名字”,另一个是一个人的“姓氏”。可能还有其他字符串,例如“最喜欢的食物”。

现在,在您的代码中,您不断发现运行时错误,因为您将参数弄混了。您可以切换“名字”和“姓氏”的顺序,或者在应该使用另一个时使用另一个。强类型语言的价值在于它会在构建时而不是运行时发现这些错误。

因此,一种可能的解决方案是仅从字符串派生类。

public class FirstName : String
{
}

public class LastName : String
{
}

现在,如果你传递了错误类型的字符串,编译器会报错。 以上是不可能的,因为 String 是密封的。 此外,“使用”语句不起作用(我认为)因为当我将它们混合时编译器不会抱怨。

using LastName = String;

当然,我可以构建包装字符串的类,然后编写强制转换方法,但这似乎比它的价值更麻烦。

【问题讨论】:

  • 请不要在标题前加上“C#”之类的前缀。这就是标签的用途。
  • 为什么不使用命名参数(在 VS2010 版本的 C# 中引入)来避免参数问题的切换或排序,而不仅仅是使用更强大的类型来让生活变得艰难? msdn.microsoft.com/en-us/library/dd264739.aspx

标签: c# string inheritance strong-typing


【解决方案1】:

我不知道您的目标是什么,但您似乎对此很认真 :) 所以一个可能的解决方案是使用通用容器类。它确实不如从密封类继承。

public class Container<T>
{
    public T Value { get; protected set; }

    public Container(T value)
    {
        Value = value;
    }
}

public class FirstName : Container<string>
{
    public FirstName(string firstName) : base(firstName) { }
}

public class LastName : Container<string>
{
    public LastName(string lastName) : base(lastName) { }
}

public class Age : Container<int>
{
    public Age(int age) : base(age) { }
}

public class Program
{
    public void Process(FirstName firstName, LastName lastName, Age age)
    {

    }
}

【讨论】:

  • 你在这里。这就是我一直在寻找的。​​span>
  • @ChuckZ。所以你将有成千上万的课程供每次使用?
  • 不是数千。只是不断混淆的两个。
【解决方案2】:

现在,在您的代码中,您不断发现运行时错误,因为您将参数弄混了。您可以切换“名字”和“姓氏”的顺序,或者在应该使用另一个时使用另一个。强类型语言的价值在于它会在构建时而不是运行时发现这些错误。

很难说出您的问题真正是什么。鉴于此,开发人员方面应该有一些责任。我们在这里谈论的究竟有多少个参数?如果您有多个参数,这通常意味着您需要重构代码。例如:

void MyMethod(string firstName, stringMiddleName, string lastName, 
 string phoneNumber, string email, string country, string city, 
 string state, string zipcode, string countryISO, 
 string pseudonym, string title, string addressLine1, string addressLine2)

显然这是令人费解的。创建一个对象ContactInfo 包装大部分(如果不是全部)这些参数,然后您可以编写:

void MyMethod(ContactInfo contact)

编辑:

如果您使用的是 VS2010,您可以使用 命名参数 功能。这允许您以不同的顺序传递它们。

string ConcatName(string firstName, string lastName)
{
    return (firstName + " " + lastName);
}

string myName = ConcatName(lastName: "Crosby", firstName: "Bryan")

输出:

布莱恩·克罗斯比

仍然会仔细查看您的代码,看看您是否可以重构方法和类。

【讨论】:

    【解决方案3】:

    别忘了创建另一个类似的类

    A-FileStreamReader : StreamReader
    B-FileStreamReader : StreamReader
    Age : int
    Phone : long
    ...
    ...
    SLaksPhoneNumer : string // added under pressure...    
    

    解决方案是,使用正确的参数调用方法,当方法要求 firstName 给它而不是 lastName...

    顺便说一句,什么会阻止你做(在编译时或在运行时):

    new FirstName("Skeet");
    new LastName("Jon");
    

    【讨论】:

    • 电话号码是字符串,而不是长字符串
    • “不要犯错”。现在为什么我没有想到:^)
    【解决方案4】:

    很难说出你的问题到底是什么。

    如果您有一个方法,例如,它需要 6 个字符串参数,并且将来可能需要 7 个,也许您应该只创建一个具有相关 6 个属性的强类型对象(将来您可以扩展添加第 7 个 - 避免需要修改方法上的签名)。然后你的方法可以只接受一个参数,它是你的强类型对象,包含你的方法的相关参数。

    【讨论】:

      猜你喜欢
      • 2021-12-15
      • 1970-01-01
      • 2021-06-14
      • 1970-01-01
      • 2013-05-30
      • 2019-01-24
      • 1970-01-01
      • 2013-01-07
      • 1970-01-01
      相关资源
      最近更新 更多