Strong-typing for strings or other sealed classes
Asked Answered
R

4

10

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. 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.

Reaves answered 26/3, 2012 at 18:2 Comment(2)
Please don't prefix your titles with "C#" and such. That's what the tags are for.Oliva
Why not use named arguments (introduced in VS2010 version of C#) to avoid the switching around or ordering of parameter problems, instead of just making life hard with more strong typing? msdn.microsoft.com/en-us/library/dd264739.aspxLikeness
K
4

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

    }
}
Kozlowski answered 26/3, 2012 at 18:18 Comment(3)
You got it here. This is what I was looking for.Reaves
@ChuckZ. So you will have thousands of classes for every use?Tarsal
Not thousands. Just the two that keep getting confused.Reaves
G
2

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:

void MyMethod(ContactInfo contact)

EDIT:

You could, if you are using VS2010, use the named parameter feature. 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.

Gilthead answered 26/3, 2012 at 18:18 Comment(0)
T
1

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...

By the way, What would prevent you doing (in compile time or in RUNTIME):

new FirstName("Skeet");
new LastName("Jon");
Tarsal answered 26/3, 2012 at 18:7 Comment(2)
Phone numbers are strings, not longsSantanasantayana
"Just don't make mistakes". Now why didn't I think of that :^)Reaves
N
0

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). Then your method can just accept the one parameter, which is your strongly typed object that contains the relevant parameters for your method.

Normalcy answered 26/3, 2012 at 18:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.