简体   繁体   English

字符串或其他密封类的强类型

[英]Strong-typing for strings or other sealed classes

I am phrasing my example in generic terms because it gets the point across without having to go into my specific problem details. 我用通用术语表述我的示例,因为它可以说明要点,而不必深入研究我的特定问题细节。

Suppose you had a bunch of methods that take strings as parameters. 假设您有一堆将字符串作为参数的方法。 Suppose that one string were a person's "first name" and another were a person's "last name". 假设一个字符串是一个人的“名字”,而另一个则是一个人的“姓氏”。 There could be other strings like "favorite food". 可能还有其他字符串,例如“最喜欢的食物”。

Now, in your code, you keep finding runtime bugs because you are getting the parameters mixed up. 现在,在代码中,您一直在查找运行时错误,因为您正在混淆参数。 You may switch the order of "first name" and "last name" or use one when you should have used the other. 您可以切换“名字”和“姓氏”的顺序,也可以在应该使用另一个时使用一个。 The value of strongly-typed languages is that it will find these bugs at build time rather than runtime. 强类型语言的价值在于它将在构建时而不是运行时发现这些错误。

So, one possible solution would be to just derive classes from string. 因此,一种可能的解决方案是仅从字符串派生类。

public class FirstName : String
{
}

public class LastName : String
{
}

Now, if you passed the wrong type of string the compiler would complain. 现在,如果您传递了错误的字符串类型,编译器将抱怨。 The above is not possible because String is sealed. 由于String是密封的,因此上述操作是不可能的。 Also, the "using" statement will not work (I think) because the compiler will not complain when I mix them up. 另外,“使用”语句将不起作用(我认为),因为当我将它们混合使用时,编译器不会抱怨。

using LastName = String;

Sure, I could build classes that wrap the string and then write cast conversion methods, but that seems like more trouble than it is worth. 当然,我可以构建包装字符串的类,然后编写强制转换方法,但这似乎比它值得的麻烦更多。

Now, in your code, you keep finding runtime bugs because you are getting the parameters mixed up. 现在,在代码中,您一直在查找运行时错误,因为您正在混淆参数。 You may switch the order of "first name" and "last name" or use one when you should have used the other. 您可以切换“名字”和“姓氏”的顺序,也可以在应该使用另一个时使用一个。 The value of strongly-typed languages is that it will find these bugs at build time rather than runtime. 强类型语言的价值在于它将在构建时而不是运行时发现这些错误。

It's hard to tell what your question really is. 很难说出您的真正问题是什么。 Given that, there should be some responsibility on the developer's side. 鉴于此,开发商应承担一些责任。 Exactly how many parameters are we talking about here? 我们在这里讨论多少个参数? If you have more than a few parameters, that generally means you need to refactor your code. 如果您有多个参数,则通常意味着您需要重构代码。 For example: 例如:

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)

Obviously that is convoluted. 显然那是令人费解的。 Create an object ContactInfo wrapping most if not all of those parameters, and then you can write: 创建一个包含大部分(如果不是全部)参数的ContactInfo对象,然后可以编写:

void MyMethod(ContactInfo contact)

EDIT: 编辑:

You could, if you are using VS2010, use the named parameter feature. 如果使用的是VS2010,则可以使用命名参数功能。 This allows you to pass them in a different order. 这使您可以以其他顺序传递它们。

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

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

Output: 输出:

Bryan Crosby 布莱恩·克罗斯比

I still would take a look at your code closely and see if you can refactor the method(s) and classes. 仍然会仔细查看您的代码,看看是否可以重构方法和类。

I don't know what your aim is, but you seem to be serious about it :) So a possible solution would be to use a generic container class. 我不知道您的目标是什么,但您似乎对此很认真:)因此,可能的解决方案是使用通用容器类。 It would indeed be less comfortable than inherit from the sealed classes. 确实比从密封类继承要舒适。

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)
    {

    }
}

Just don't forget to make another classes like 只是别忘了再上一堂课

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

The solutions is, call the methods with the right parameters, when the method ask for firstName give it and not lastName... 解决方法是,当方法要求firstName给它而不是lastName时,使用正确的参数调用方法。

By the way, What would prevent you doing (in compile time or in RUNTIME): 顺便说一下,什么会阻止您这样做(在编译时或在运行时):

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

It's hard to tell what exactly your question is. 很难说出您的问题到底是什么。

If you have a method, for instance, that takes 6 string parameters, and might in the future take 7, perhaps you ought to just create a strongly typed object that has the relevant 6 properties (which in the future you can extend to add the 7th--obviating the need to modify the signature on the method). 例如,如果您有一个采用6个字符串参数的方法,并且将来可能采用7个方法,也许您应该只创建一个具有相关6个属性的强类型对象(将来您可以扩展该属性以添加7-无需修改方法上的签名)。 Then your method can just accept the one parameter, which is your strongly typed object that contains the relevant parameters for your method. 然后,您的方法可以只接受一个参数,这是您的强类型对象,其中包含与方法相关的参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM