Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#中,我是否应该使用struct包装对象以实现其他接口?_C#_.net_Oop_Design Patterns_Struct - Fatal编程技术网

在C#中,我是否应该使用struct包装对象以实现其他接口?

在C#中,我是否应该使用struct包装对象以实现其他接口?,c#,.net,oop,design-patterns,struct,C#,.net,Oop,Design Patterns,Struct,我想重用来自第三方库的现有类,但它没有实现某些必需的接口。我正在考虑将它包装在一个结构中,以实现所需的接口(基本上就像Scala那样)。对于这个用例,我之所以更喜欢struct而不是class,是因为它只存储一件东西:包装的对象,而且它可能不会招致性能损失?但我不确定如果我将struct传递给某个接收接口的方法,是否会发生装箱?这种方法还有其他缺点吗?是的,在这种情况下,如果不希望同时实现两个接口(现有的+要添加的额外接口),可以使用struct。包装不会有任何开销,因为struct只存储引用,

我想重用来自第三方库的现有
,但它没有实现某些必需的接口。我正在考虑将它包装在一个
结构中
,以实现所需的接口(基本上就像Scala那样)。对于这个用例,我之所以更喜欢
struct
而不是
class
,是因为它只存储一件东西:包装的对象,而且它可能不会招致性能损失?但我不确定如果我将
struct
传递给某个接收接口的方法,是否会发生装箱?这种方法还有其他缺点吗?

是的,在这种情况下,如果不希望同时实现两个接口(现有的+要添加的额外接口),可以使用struct。包装不会有任何开销,因为struct只存储引用,而不存储整个对象。因为对象总是通过引用进行访问,即存储在堆上。所以不会有任何性能惩罚但不建议使用此方法
但是,如果您有可以同时使用两个接口实现的情况,则应该定义一个新的派生类,该派生类将具有一个变量来存储基类的对象。通过这种方式,您可以使用派生类的对象,并将指向基类对象的变量保持为null。
请参阅了解实施的详细信息。

另请参考

更简单的方法是在代码中直接继承第三方类,然后在此派生类上实现所需的接口。没有拳击;只传递引用。

Microsoft给出了非常明确和直接的理由,说明您应该使用
结构而不是

√ 如果类型的实例很小,通常是短命的,或者通常嵌入在其他对象中,请考虑定义结构而不是类。 避免定义结构,除非该类型具有以下所有特征:

  • 它在逻辑上表示单个值,类似于基本类型(int、double等)
  • 它的实例大小小于16字节
  • 它是不变的
  • 它不必经常装箱


看来这不是你的案子。顺便说一句,如果将
struct
传递给采用
接口的方法,则会发生装箱。还要考虑到结构不支持继承,并且它们不能有显式的无参数构造函数。

如果通过接口引用访问结构,它将被装箱,从而否定了大部分好处。在这种情况下,这是对装饰器模式的滥用。如果您想在运行时向对象添加额外的职责,那么它非常有用。显然,它似乎是一个@Olexander:正如shengmin所说,“我想重用第三方库中的一个现有类,但它没有实现一些必需的接口。”他想实现一些现有库中尚未存在的接口。如果他只是想让第三方API与他的API/类兼容,那么适配器可以毫无疑问地使用。@Olexander:装饰器和适配器之间的主要区别是什么?我认为这里的命名是非常脆弱和主观的。这种模式之间的界限非常模糊和不清楚。P.S.@abatishchev,如果是采访,我将回答=)Decorator允许在运行时向装饰对象添加附加功能,Adapter允许将现有接口适应不同类型的使用者(在设计时)。两者都是一种委托技术的实现,但区别很明显,不是吗?@abatishchev,我认为模式最有用的地方是用公认的名称命名=)@shengmin:您可以定义一个包含变量的包装器类来保存第三方类对象,并实现需要实现的额外类。