Adding a structure: interface to the <interfaces>

I need to pass structures as value types in a list. Suppose I have a structure that derives from an interface:

 interface IFoo { ... } struct Foo1 : IFoo { ... } struct Foo2 : IFoo { ... } //Some other class which contains this: List<IFoo> listOfFoo; 

I know if I did it like this: IFoo foo = new Foo1() , this would turn the value into a link (box).

  • Would structures not be passed as a reference if I added Foo1 or Foo2 to a List<IFoo> ?
  • If this is not the case, is it safe to do List<object> and add only to these structures, or would it be better to make MemberwiseClone in the class?

I am also looking for efficiency, as it will be for detecting collisions on the tile map.

+5
source share
3 answers

If you have a List where I is the interface, and you add elements like F1 and F2 , where both implement I , then when you extract either of the two elements from the list, you can check the link type using the ** is keyword **, and start applying the proper cast to the element that you got from the list.

For instance:

 struct Foo1 : IFoo {...} struct Foo2 : IFoo {...} List<IFoo> listOfFoo = new List<IFoo>(); IFoo foo1 = new Foo1(); IFoo foo2 = new Foo2(); listOfFoo.Add(foo1); listOfFoo.Add(foo2); // lets retrieve the first element and check if it a Foo1 value type if(listOfFoo[0] is Foo1){ // cast element from List to Foo1 Foo1 foo = (Foo1) listOfFoo[0]; } 

Since we are dealing with structures, when an item from a list returns to its original value type, it must be unpacked. But too much unboxing and boxing can hit performance, and since you want to do something like collision detection, it can lead to poor performance.

Do you have to use structures? Due to changes in boxing made to variables, it may not behave correctly if you perform operations with objects stored in boxed boxes, and, as I said, too much boxing can bring you bad results.

In my opinion, a class with MemberwiseClone would be better.

You can read this article on MSDN, which details the pros and cons for both structures and classes, this can help you better understand when to use one or the other.

+2
source
  • Structures will be placed in a box. Why not? Each value in the List<IFoo> must be IFoo , so each added instance of the structure is converted - through the box.

  • Structures are still in the box because object also a reference type. In your scenario, there is simply no way to avoid boxing unless you declare the list a specific value type ( List<Foo1> or List<Foo2> ).

In general, using structures for "efficiency" is not at all a simple or obvious thing. In particular, simply clicking struct , where you otherwise write a class , does not guarantee that your code will work better. First write your code in an obvious way (and obviously what it means: using classes), then determine (through profiling) if you need to optimize it, and if so, how.

+5
source

Each structure definition actually creates two kinds of things in .NET: the type of the heap object ("boxed") and the type of storage ("unboxed"). References to heap objects are stored in storages of an interface type, therefore, to store an unboxed structure of an interface type variable, its contents must be copied to an instance of the heap object type.

A generic type parameter may be limited by an interface to identify the type of structure storage; then you can call the interface methods in the storage location in question without a box. In some cases, this can provide some major benefits. Unfortunately, there is no way to tell the compiler "I don’t want this thing to be boxed, and if I do everything that requires boxing, I would prefer the compiler to squander than quietly insert the conversion of the box." Therefore, when using structures that implement interfaces, special care is required; if someone does not wish to be so careful, it is best that all structures try either:

  • behave like objects (in this case they should be small and prohibit any mutation methods other than a complete replacement) or

  • - this is nothing more than a group of variables glued together with duct tape (i.e., a collection of open fields).

Things that implement interfaces outside of a few special cases, such as IEquatable<T> , whose sole purpose is centered around structures, should usually be classes.

0
source

Source: https://habr.com/ru/post/1213254/


All Articles