Вопрос

Возможный дубликат:
Безопасно ли структурам реализовывать интерфейсы?

Возьмите этот код:

interface ISomeInterface
{
    public int SomeProperty { get; }
}

struct SomeStruct : ISomeInterface
{
    int someValue;

    public int SomeProperty { get { return someValue; } }

    public SomeStruct(int value)
    {
        someValue = value;
    }
}

а затем я делаю это где-то:

ISomeInterface someVariable = new SomeStruct(2);

это SomeStruct коробочный в данном случае?

Это было полезно?

Решение

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

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

Другие советы

Точка Джона верна, но в качестве побочной записи есть одно небольшое исключение из правила; Дженерики. Если у тебя есть where T : ISomeInterface, тогда это ограниченный, и использует Специальный код OPCode. Отказ Это означает, что интерфейс может быть использован без заниматься боксом. Например:

public static void Foo<T>(T obj) where T : ISomeInterface {
    obj.Bar(); // Bar defined on ISomeInterface
}

Это делает нет включать в себя бокс даже по значению типа T. Отказ Однако, если (в том же Foo) вы делаете:

ISomeInterface asInterface = obj;
asInterface.Bar();

Тогда это коробки как раньше. То ограниченный Только применяется напрямую к T.

Я добавляю это, чтобы, надеюсь, пролить немного больше осветите ответы, предложенные Джоном и Марком.

Рассмотрим этот необщий метод:

public static void SetToNull(ref ISomeInterface obj) {
    obj = null;
}

Хм...установка ref параметр на ноль.Это возможно только для ссылочного типа, верно?(Ну или за Nullable<T>;но давайте проигнорируем этот случай, чтобы не усложнять задачу.) Таким образом, тот факт, что этот метод компилируется, говорит нам о том, что переменная, объявленная как принадлежащая к некоторому типу интерфейса, должна рассматриваться как ссылочный тип.

Ключевая фраза здесь «объявлена ​​как»:рассмотрите эту попытку вызвать вышеуказанный метод:

var x = new SomeStruct();

// This line does not compile:
// "Cannot convert from ref SomeStruct to ref ISomeInterface" --
// since x is declared to be of type SomeStruct, it cannot be passed
// to a method that wants a parameter of type ref ISomeInterface.
SetToNull(ref x);

Конечно, причина, по которой вы не можете пройти x в приведенном выше коде, чтобы SetToNull в том, что x необходимо будет объявить как ISomeInterface чтобы ты смог пройти ref x -- и нет потому что компилятор волшебным образом знает это SetToNull включает в себя строку obj = null.Но это лишь подтверждает мою точку зрения:тот obj = null линия легальна именно потому, что это было бы незаконный передать переменную нет объявлен как ISomeInterface к методу.

Другими словами, если переменная объявлена ​​как ISomeInterface, для него можно установить значение null, в чистом виде.И это потому, что интерфейсы являются ссылочными типами - следовательно, объявление объекта как интерфейса и присвоение его объекту типа значения блокирует это значение.

Теперь, с другой стороны, рассмотрим этот гипотетический общий метод:

// This method does not compile:
// "Cannot convert null to type parameter 'T' because it could be 
// a non-nullable value type. Consider using 'default(T)' instead." --
// since this method could take a variable declared as, e.g., a SomeStruct,
// the compiler cannot assume a null assignment is legal.
public static void SetToNull<T>(ref T obj) where T : ISomeInterface {
    obj = null;
}

То MSDN Документация Рассказывает нам, что структуры являются ценностью, а не ссылочными типами. Они в штучной упаковке при преобразовании в / из переменной типа object. Отказ Но центральный вопрос здесь: как насчет переменной типа интерфейса? Поскольку интерфейс также может быть реализован классом, то это должно быть равносильно преобразовывать из значения ссылочного типа, как уже сказал Джон Скелет уже, следовательно, да в боксе произойдет. Больше обсуждения в блоге MSDN.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top