Присвоєння стану при невідомому типі в Visual C # (Sharp)

При роботі з узагальненнями NET одна з найбільш поширених проблем породжується необхідністю працювати з власними типами (proper types) Так, в реалізації інтерфейсу iworksheet необхідно реалізувати метод AssignCellState (), визначений В інтерфейсі IWorksheetSerialize

Але тут мається проблема, яка полягає в тому, що функція передається як параметр певного тип і присвоюється змінної CellState, яка є дрім невизначеним узагальненням NET Метод AssignCellstateO реалізується наступним чином:

public void AssignCellState(int row, int col, object value) { CellState[row, col] = (BaseType)value

&gt&nbsp

Код виглядає дуже простим і безневинним, але насправді приховує багато можливих проблем Тут значення параметра value є типу object Потім для його перетворення в тип BaseType – т к CellState визначений цим типом – виконується операція приведення типів У більшості випадків, якщо значення правильного типу, цей код буде працювати

Але наступний код згенерує виняток: IWorksheet worksheet = new Worksheet () worksheetDimension (10, 10)

string buffer = &quothello worlds-

worksheet AssignCellState (1, 2, buffer)

Мінлива worksheet оголошена типом double При виклику методу AssignCellstateO осередку (1,2) присвоюється тип string Виклик методу AssignCellState про не представляє проблем, але в його реалізації операція прваіванія буде неуспішною, т к ми не можемо просто так привласнити тип string типу double Це, звичайно ж, породжує питання, навіщо взагалі потрібна функція типу object Тому, що іноді у нас просто немає іншого виходу і потрібно створити метод загального обєкта Правильним способом виклику методу буде наступний:

IWorksheet&ltdouble&gt worksheet = new Worksheet&ltdouble&gt() worksheetDimension(10, 10)

string buffer = &quothello world" worksheetAssignCellState(l, 2, DoubleParse(buffer))

Виділений жирним шрифтом код показує, що значення типу string преобра за допомогою методу DoubleParse () в значення типу double Це преобразаніе, звичайно ж, буде невдалим, т к буфер не є строковим предстаеніем числа, але це вже інша проблема

Іншим способом вирішити цю проблему буде взагалі не піднімати даного ВОПР, і оголосити метод узагальненням NET Перевага узагальнень NET заключтся в тому, що вони дозволяють типову безпеку виконання, НЕ змушуючи явно користувача реалізовувати процедури перетворення Розглянемо наступне оголошення методу AssignCeiistate () із застосуванням узагальнень NET:

public void AssignCellState&ltValueType&gt(int row, int col, ValueType value) { if  (typeof(BaseType)IsAssignableFrom(typeof(ValueType)))  {

CellState[row, col] = (BaseType)(object)value

}

else if (value is string &amp&amp

typeof(double)IsAssignableFrom(typeof(BaseType)))  { CellState[row, col] =

(BaseType)(object)doubleParse((string)(object)value)

}

else {

throw new InvalidCastException(&quotCould not perform conversion&quot)

}

}

Стан, який потрібно присвоїти комірці, є параметром узагальнення

. NET, чий тип визначений як ValueType Ми можемо тільки припускати, яким є конкретний тип ValueType визначення типу робиться, коли викликається метод AssignCellstateo () Припустимо, що викликається наступний метод:

string buffer = &quothello world" worksheetAssignCellState(l, 2, buffer)

У даному випадку тип ValueType буде string, хоча ми це явно і не вказували Однією з можливостей, що надаються методами узагальнень NET, є неявне визначення типів У наступному коді метод AssignCellstateo () Іользуется явним чином

string buffer = &quothello world" worksheetAssignCellState&ltstring&gt(1, 2, buffer)

Знаючи, що ValueType має тип string, метод спочатку виконає перевірку, можна

ЧИ ValueType прісваіват ь BaseType:

if (typeof(BaseType)IsAssignableFrom(typeof(ValueType))) {

Код досить хитромудрий, т к для визначення можливості присвоювання одного типу іншому в ньому використовуєтьсявідображення(Reflection) По суті,

він запитує, чи можна привласнити значення CellState допомогою приведення тов Можна також спробувати обійтися і без оператора if, але в такому випадку сущтвует зайвий ризик виникнення винятку Якщо операція привласнення допуіма, то привласнення виконується в двокроковий операції приведення типів:

CellState[row, col] = (BaseType)(object)value

Тут ми спочатку перетворимо тип в object, після чого виконуємо перетворення в BaseType, який якраз і є типом, яким був оголошений лист ОПЕРУ приведення до типу object є обовязковою, т к в іншому випадку компілятор С # видасть помилку про неможливість виконання приведення

Але припустимо, що тип не можна привласнити безпосередньо Скажімо, що змінна value посилається на строкове представлення числа У такому випадку можна з помь ю Відбитки Перевірити, якими типами ЯВЛЯЮТЬСЯ ValueType І BaseType, і ви – конати перетворення самостійно:

else if (value is string &amp&amp

typeof(double)IsAssignableFrom(typeof(BaseType)))

У першій частині оператора if виконується перевірка, чи є value змінної З ТИПОМ String, а в другій виконується Перевірка, можна Про ЧИ BaseType привласнити double Позитивний результат обох перевірок означає, що вводяться дані відносяться до типу string, а тип листа – double відповідно, для преобразова потрібно лише викликати метод Double Parse ()

Функціональність автоматичного перетворення не зменшує необхідний обсяг коду, але централізує його і робить його загального призначення Зухвалому коду зазвичай не потрібно буде піклуватися про виконання найбільш поширених перетворень, т к вони виконуватимуться автоматично Звичайно ж, предпагется, що ці найбільш поширені перетворення реалізовані прраммістом Для тих же перетворень, які не можна виконати, вкидається виняток приведення, точно так само, як це зробив би і початковий метод AssignCeilstate () на основі обєкта

Загалом, метод AssignCeilstateo () з параметрами узагальнення NET предостаяет можливість акуратно привласнити значення листу і акуратний і сопровоаемий метод для виконання перетворення Таким чином, задовольняється початкове вимога мати можливість безпечного змішання типів

Джерело: Гросс К С # 2008: Пер з англ – СПб: БХВ-Петербург, 2009 – 576 е: ил – (Самовчитель)

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*