Некоторые из существующих ответов не совсем верны. Вы не можете использовать типы non-nullable с as
, потому что результатом as
является нулевое значение типа, если первый операнд на самом деле не имеет подходящего типа.
Однако вы можете использовать as
с типами значений... если они допускают значение NULL:
int a = 10;
object o = a;
int? x = o as int?; // x is a Nullable<int> with value 10
long? y = o as long?; // y is a Nullable<long> with the null value
Итак, вы можете использовать:
Call? call = line.Tag as Call?;
Затем вы можете использовать его как:
if (call != null)
{
// Do stuff with call.Value
}
Два предостережения, хотя:
- По моему опыту, это медленнее, чем простое использование
is
с последующим приведением
- You should seriously reconsider your current
Call
type:
- It's exposing public fields, which is generally poor encapsulation
- Это изменяемый тип значения, что почти наверняка является ошибкой.
Я настоятельно рекомендую вам вместо этого сделать его классом - и в этот момент эта проблема все равно исчезнет.
Еще одна мысль: если тег всегда должен быть Call
, то лучше его привести:
Call call = (Call) line.Tag;
Таким образом, если данные не соответствуют вашим ожиданиям (например, есть какая-то ошибка, из-за которой Tag
не является Call
), вы узнаете об этом заранее, а не после того, как потенциально проделаете какую-то другую работу. Обратите внимание, что это приведение будет вести себя по-разному в зависимости от того, является ли Call
структурой или классом, если Tag
имеет значение null, вы можете привести нулевое значение к переменной ссылочного типа (или типу значения, допускающего значение NULL), но не к не- тип значения, допускающий значение NULL.
person
Jon Skeet
schedule
09.12.2010