Строгая типизация для строк или других закрытых классов - PullRequest
8 голосов
/ 26 марта 2012

Я формулирую свой пример в общих терминах, потому что он дает смысл без необходимости вдаваться в подробности моей конкретной проблемы.

Предположим, у вас есть несколько методов, которые принимают строки в качестве параметров. Предположим, что одна строка была «именем человека», а другая - «фамилией» человека. Могут быть и другие строки, например «любимая еда».

Теперь в вашем коде вы продолжаете находить ошибки времени выполнения, потому что вы путаете параметры. Вы можете изменить порядок «имя» и «фамилия» или использовать один, когда вы должны были использовать другой. Значение строго типизированных языков заключается в том, что они находят эти ошибки во время сборки, а не во время выполнения.

Итак, одним из возможных решений было бы просто извлечь классы из строки.

public class FirstName : String
{
}

public class LastName : String
{
}

Теперь, если вы передали неправильный тип строки, компилятор будет жаловаться. Вышеупомянутое не возможно, потому что Строка запечатана. Кроме того, оператор "using" не будет работать (я думаю), потому что компилятор не будет жаловаться, когда я их смешиваю.

using LastName = String;

Конечно, я мог бы создавать классы, которые переносят строку, а затем писать методы преобразования приведения, но это кажется большим количеством проблем, чем оно того стоит.

Ответы [ 4 ]

2 голосов
/ 26 марта 2012

Я не знаю, какова ваша цель, но вы, кажется, серьезно относитесь к этому :) Так что возможным решением было бы использование универсального класса контейнера. Это действительно было бы менее удобно, чем наследовать от запечатанных классов.

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

    }
}
2 голосов
/ 26 марта 2012

Теперь в вашем коде вы продолжаете находить ошибки времени выполнения, потому что вы путаете параметры.Вы можете изменить порядок «имя» и «фамилия» или использовать один, когда вы должны были использовать другой.Значение строго типизированных языков в том, что они находят эти ошибки во время сборки, а не во время выполнения.

Трудно сказать, каков ваш вопрос на самом деле .Учитывая это, на стороне разработчика должна быть некоторая ответственность.Точно, о каких параметрах мы говорим здесь?Если у вас есть несколько параметров, это, как правило, означает, что вам нужно реорганизовать ваш код.Например:

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

Вывод:

Брайан Кросби

I все еще внимательно посмотрю на ваш код и посмотрим, сможете ли вы провести рефакторинг методов и классов.

1 голос
/ 26 марта 2012

Только не забудьте создать другие классы, такие как

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

Решения таковы: вызывайте методы с правильными параметрами, когда метод запрашивает firstName, а не lastName ...

Кстати, что бы вам мешало делать (во время компиляции или в RUNTIME):

new FirstName("Skeet");
new LastName("Jon");
0 голосов
/ 26 марта 2012

Трудно сказать, каков именно ваш вопрос.

Если у вас есть метод, например, который принимает 6 строковых параметров и может в будущем принять 7, возможно, вам следует просто создать строго типизированный объект, который имеет соответствующие 6 свойств (которые в будущем вы можете расширить добавить 7-е - устранение необходимости изменения подписи на методе). Тогда ваш метод может просто принять один параметр, который является вашим строго типизированным объектом, который содержит соответствующие параметры для вашего метода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...