В .NET, если вы передаете структуру в метод с параметром интерфейса, это - это значение?

StackOverflow https://stackoverflow.com/questions/5363587

  •  27-10-2019
  •  | 
  •  

Вопрос

Из простого теста я вижу, что если вы передаете структуру в метод, он передается по значению, но если вы сначала присвоили его интерфейсу, он передается ссылкой.

interface IFoo { int Val { get; set; } }
struct Foo : IFoo { public int Val { get; set; } }

void Bar(IFoo foo) { foo.Val = 1; }

Foo foo = new Foo();
IFoo ifoo = new Foo();

Bar(foo);
Bar(ifoo);

Console.WriteLine(foo.Val);  // 0, passed by value
Console.WriteLine(ifoo.Val); // 1, passed by ref

Итак, мой вопрос: есть ли еще операция по боксу для передачи структуры в такой?

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

Решение

Всякий раз, когда структура преобразуется в интерфейс, он попадает в штуку.

Foo foo = new Foo();//Doesn't box yet
IFoo ifoo = new Foo();//Boxes

Bar(foo);//creates a new boxed copy
Bar(ifoo);//Uses the old boxed version created in line 2

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

void Bar<T>(T foo)
    where T:IFoo 
{
}

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


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

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

Интерфейсы - все это ссылочные типы, поэтому бокс происходит на линии

IFoo ifoo = new Foo();

а не при звонке Bar.

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