C #: преобразование типов данных во время выполнения - PullRequest
6 голосов
/ 01 августа 2011

Я впервые использую StackOverflow. Я нашел много ответов на многие из моих вопросов здесь раньше, и поэтому я подумал, что попробую спросить что-то сам.

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

Проект включает в себя синтаксический анализатор NBT, который я решил написать сам, поскольку он будет использоваться для более или менее настраиваемого варианта файлов NBT, хотя основной принцип тот же: поток двоичных данных с предопределенными «ключевыми словами» для конкретных видов тегов. Я решил попробовать создать один класс только для всех типов тегов, поскольку структура тегов очень похожа - все они содержат тип и полезную нагрузку. И вот где я застрял. Я хочу, чтобы полезная нагрузка имела определенный тип, который, когда явное преобразование выполняется неявно, выдает ошибку.

Лучшее, что я могу придумать, - это сделать полезную нагрузку типа Object или динамической, но это позволит неявно выполнять все преобразования:

Int64 L = 90000;
Int16 S = 90;
dynamic Payload; // Whatever is assigned to this next will be accepted
Payload = L; // This fine
Payload = S; // Still fine, a short can be implicitly converted to a long
Payload = "test"; // I want it to throw an exception here because the value assigned to Payload cannot be implicitly cast to Int64 (explicit casting is ok)

Есть ли способ сделать это? Я хотел бы решить эту проблему, сообщив C #, что с этого момента, хотя полезная нагрузка является динамической, она будет выдавать исключение, если назначенное значение не может быть неявно преобразовано в тип текущего значения - если, конечно, это не сделано явно.

Я открыт для других способов достижения этого, но я бы хотел избежать чего-то подобного:

public dynamic Payload
{
    set
    {
        if(value is ... && Payload is ...) { // Using value.GetType() and Payload.GetType() doesn't make any difference for me, it's still ugly
            ... // this is ok
        } else if(...) {
            ... // this is not ok, throw an exception
        }
        ... ... ...
    }
}

Ответы [ 2 ]

3 голосов
/ 01 августа 2011

Рассматривали ли вы использование дженериков? Это автоматически даст вам проверку во время компиляции, какие преобразования разрешены.

class GenericTag<T>
{
    public GenericTag(T payload)
    {
        this.Payload = payload;
    }

    public T Payload { set; get; }
}

// OK: no conversion required.
var tag2 = new GenericTag<Int64>(Int64.MaxValue);

// OK: implicit conversion takes place.
var tag1 = new GenericTag<Int64>(Int32.MaxValue);

// Compile error: cannot convert from long to int.
var tag4 = new GenericTag<Int32>(Int64.MaxValue);

// Compile error: cannot convert from string to long.
var tag3 = new GenericTag<Int64>("foo");
0 голосов
/ 01 августа 2011

Если вы знаете, что вам понадобится Int64, почему бы не использовать Convert.ToInt64?

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