Фактически, цель выраженного вами класса Number
состоит в том, чтобы обойти компилятор и разрешить неявное приведение, которое может быть недопустимым.Вы говорите компилятору , а не , чтобы проверить тип, и вместо этого разрешаете исключение времени выполнения, если приведение не допустимо.
Попытка заставить компилятор выдать предупреждение означает, что попытка заставить его делать именно то, что вы сказали, не делать.
В некотором смысле это ничем не отличается от использования object
вместо Number
.
Если вы решите использовать object
, то компилятор вам не поможет.Вы отказываетесь от безопасности типов, а это значит, что вы должны каким-то образом убедиться, что вы отслеживаете, откуда берется каждое значение, и во что оно может или не может быть преобразовано, чтобы вы не получили ошибок времени выполнения.
Безопасность типов - это просто безопасность.Это защитные ограждения, которые помогают нам не писать код, который потерпит неудачу при запуске.Я рекомендую всегда использовать его, если нет действительно важной причины не делать этого, как правило, когда конкретный тип не имеет значения.Обычно это так.
Вот еще один способ взглянуть на это: если различные типы, в которые вы хотите неявно преобразовать, не имеют общности, тогда нет смысла передавать экземпляр методу, который может или не может бытьвозможность использовать его.
С другой стороны, предположим, что есть общность.Скажем, например, у каждого из ваших базовых типов есть свойство, которое возвращает строку, но это свойство отличается для каждого типа.В этом случае вы можете создать интерфейс, например:
public interface IHasMyStringProperty
{
string GetTheString { get; }
}
Затем создайте оболочку для разных классов, примерно так:
public class Foo
{
public string FooString { get; }
}
public class FooWrapper : IHasMyStringProperty
{
private readonly Foo _foo;
public FooWrapper(Foo foo)
{
_foo = foo;
}
public string GetTheString => _foo.FooString;
}
Обратите внимание, что мы необновление класса Foo
для реализации интерфейса, хотя это тоже может быть вариантом.Вместо этого мы создаем общий интерфейс и создаем оболочки (или адаптеры) для адаптации различных типов к этому общему интерфейсу.(У вас могут быть оба - классы, которые реализуют интерфейс, и классы, которые нуждаются в обертках.) В результате получается безопасность типов.Мы пишем все остальные наши методы для работы только с IHasMyStringProperty
.Если мы хотим передать какой-то другой тип, нам просто нужно определить оболочку, которая реализует этот интерфейс.