繁体   English   中英

添加Struct:接口到列表<Interface>

[英]Adding Struct : Interface to a List<Interface>

我需要将结构作为值类型传递给列表。 假设我有一个派生自接口的结构:

interface IFoo
{
    ...
}
struct Foo1 : IFoo { ... }
struct Foo2 : IFoo { ... }

//Some other class which contains this:
List<IFoo> listOfFoo;

我知道如果我这样做: IFoo foo = new Foo1() ,它会将值转换为引用(装箱)。

  1. 如果我将Foo1Foo2添加到List<IFoo> ,结构是否不会作为引用传递?
  2. 如果没有,是否可以安全地执行List<object>并且只添加这些结构,或者在类上进行MemberwiseClone会更好吗?

我也在寻找效率,因为这将用于瓦片地图中的碰撞检测。

  1. 结构将被装箱。 他们为什么不呢? List<IFoo>每个值都必须是IFoo ,因此您添加的每个结构实例都将通过装箱进行转换。

  2. 结构仍然是盒装的,因为object也是引用类型。 在您的场景中,除非您将列表声明为特定值类型( List<Foo1>List<Foo2> ),否则根本无法避免装箱。

通常,使用结构来表示“效率”并不是一件简单或明显的事情。 特别是,简单地夹紧在struct ,其中否则你写的class是不能保证让你的代码更好的表现。 首先以明显的方式编写代码(这里显而易见的意思是:使用类),然后确定(通过分析)是否需要优化它,如果需要,如何进行优化。

如果你有一个List,其中是一个接口,你添加F1F2类型的元素,其中两个都实现了I接口,那么当您从List中检索任何两个元素时,您可以使用关键字*检查引用的类型*是**并继续将适当的强制转换应用于从List中获得的元素。

例如:

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's a Foo1 value type
if(listOfFoo[0] is Foo1){
    // cast element from List to Foo1
    Foo1 foo = (Foo1) listOfFoo[0];
}

由于我们正在处理结构,当List中的元素被转换回原始值类型时,它应该是unboxed。 但是太多的拆箱和装箱可以达到性能,因为你想要执行碰撞检测之类的东西,这可能会带来低性能。

您是否必须使用结构? 由于对存储的盒装对象执行操作,对变量执行的装箱更改可能无法正常运行,并且正如我所提到的,太多拳击可能会给您带来不良结果。

在我看来,使用MemberwiseClone的课程会更好。

你可以阅读文章在MSDN上,详细说明利弊两个结构和类,这可能会帮助您更好地了解何时使用一个或另一个。

每个结构定义实际上在.NET中创建了两种东西:堆对象(“盒装”)类型和存储位置(“未装箱”)类型。 接口类型存储位置保存堆对象引用,因此将未装箱的结构存储到接口类型变量将要求将其内容复制到堆对象类型的实例。

受约束于接口的泛型类型参数可以识别结构存储位置类型; 然后,可以在没有装箱的情况下调用所讨论的存储位置上的接口方法。 在某些情况下,这可以提供一些主要的性能优势。 不幸的是,没有办法告诉编译器“我不想把这个东西装箱,如果我做任何需要装箱的东西,我宁愿让编译器发出尖叫声而不是默默插入一个拳击转换”。 因此,在使用实现接口的结构时需要特别小心; 如果一个人不愿意这样照顾,最好让所有结构都试图:

  • 表现得像对象(在这种情况下,它们应该很小,不允许任何突变方法,而不是完全替换)或

  • 只不过是用胶带粘在一起的变量组(即一堆公共字段)。

实现接口的东西,除了IEquatable<T>之外的一些特殊情况,其唯一目的是围绕结构,通常应该是类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM