ICloneable深复制与浅复制

open-mmlab / mmpose安装、使用教程 mmpose安装、使用教程mmpose安装教程1. 安装mmcv-full2. 安装MMPose2. 安装mmdet使用教程1. 预测图片2. 预测视频 mmpose mmpose是商汤旗下有又一款好用的工具箱,主要是针对姿态识别任务开发的,包括人体姿态识别和动物姿态识别。里面继承很多现成的网络可以供大家使用,并且提供了训练好的权重。用户可以更具自己的需求训练自己的数据,或者直接应用他们的结果,反正就是很全面啦!!!! github连接:https://github.com/open-mmlab/mmpos 阅读详情

 http://hi.baidu.com/lovemyselfbest/blog/item/9e78bd01d0f1c1d2277fb587.html

c# 深复制与浅复制
2008/01/18 11:37

ICloneable听起来是个好主意:可以为那些支持复制的类型实现ICloneable接口。如果不想支持复制,那就不要实现它。但是我们的类型并非活在真空中。让一个类型支持ICloneable接口会影响它的派生类。一旦类型支持ICloneable接口,那么它所有的派生类也都必须支持它。而且,其所有成员类型也都要支持ICloneable接口,或者有其他创建复制的机制。最后,当我们设计的类型包含交织成网状的对象时,支持深复制将变得很困难。ICloneable接口在其官方的定义里很巧妙地绕过了这个问题,其定义如下:ICloneable接口或者支持深复制(deep copy),或者支持浅复制(shallow copy)。浅复制指的是新对象包含所有成员变量的副本,如果成员变量为引用类型,那么新对象将和原对象引用同样的对象。深复制指的也是新对象包含所有成员变量的副本,但是所有引用类型的成员变量将被递归地克隆。对于C#的内建类型,例如整数,深复制和浅复制产生的是同样的结果。那么我们的类型应该支持哪一个?这要根据具体类型而定。但是在同一个对象中混合浅复制和深复制会导致许多不一致的问题。当涉足ICloneable接口时,这样的问题很难逃脱。大多数情况下,避免ICloneable接口反倒会获得一个比较简单的类——对类的客户来讲比较容易使用,对创建者来讲也比较容易实现。

任何只包含内建类型成员的值类型都不需要支持ICloneable接口;一个简单的赋值语句对struct的值所做的复制要比Clone()来得高效得多。Clone()必须对返回值进行装箱,才能转换为一个System.Object引用。调用者则必须进行强制转型才能获取真正的值。值类型默认的复制支持对我们来说已经足够了。我们没有必要再编写Clone()函数来重复这项工作。

如果值类型中包含引用类型呢?最明显的例子是包含字符串:

public struct ErrorMessage

{

private int errCode;

private int details;

private string msg;

// 忽略细节。

}

字符串是一个特殊的例子,因为string是一个具有常量性的类。如果我们对ErrorMessage对象进行赋值,两个ErrorMessage对象都将引用同一个字符串。但这并不会导致任何问题,而这放到一个普通的引用类型就会出现问题。通过任何一个对象更改msg变量,都会创建一个新的string对象(参见条款7)。

更一般的情况——创建一个包含任意引用类型变量的struct——就比较复杂了。不过这种情况相当少见。C#语言为struct提供的内建赋值操作创建的是一个浅复制——即两个struct引用的是同一个引用类型对象。要创建一个深复制,我们需要克隆其内包含的引用类型,而且需要确知其Clone()方法支持深复制。无论哪种情况,我们都没有必要为值类型添加ICloneable接口支持——赋值操作符可以创建任何值类型的新副本。

综上所述,对值类型来讲,提供ICloneable接口的理由不够充分。下面我们来看引用类型。引用类型要通过支持ICloneable接口来表明自身支持浅复制或者深复制。但是在为一个类添加ICloneable接口支持时,我们要审慎行事,因为那样做会强制要求该类的所有派生类也都必须支持ICloneable接口。考虑下面两个类:

class BaseType : ICloneable

{

private string _label = "class name";

private int [] _values = new int [ 10 ];

public object Clone()

{

    BaseType rVal = new BaseType( );

条款27:避免ICloneable接口  154

    rVal._label = _label;

    for( int i = 0; i < _values.Length; i++ )

      rVal._values[ i ] = _values[ i ];

    return rVal;

}

}

class Derived : BaseType

{

private double [] _dValues = new double[ 10 ];

static void Main( string[] args )

{

    Derived d = new Derived();

    Derived d2 = d.Clone() as Derived;

    if ( d2 == null )

      Console.WriteLine( "null" );

}

}

如果运行上面的程序,我们将发现d2的值为null。Derived类从BaseType类中继承了ICloneable.Clone()方法,但是继承来的实现对Derived类型来讲却是不正确的,因为它仅仅克隆了基类。BaseType.Clone()创建了一个BaseType对象,而非一个Derived对象。这就是测试程序中d2返回null的原因——它不是一个Derived对象。但是,即使我们能够克服这个问题,BaseType.Clone()也不能对Derived中定义的_dValues数组进行正确的复制。当我们的类型实现了ICloneable接口,就会强制要求其所有派生类也实现ICloneable接口。实际上,这时候我们应该提供一个挂钩函数(hook function)来允许所有派生类使用我们的实现(参见条款21)。为了支持克隆,派生类只可以添加那些支持ICloneable接口的值类型或引用类型成员变量。这对所有的派生类来说是一个非常严格的限制。因此我们说,为基类添加ICloneable接口支持通常会为其派生类带来一些负担,所以我们应该避免在非密封(nonsealed)类中实现ICloneable接口。

如果整个类层次必须实现ICloneable接口,我们可以创建一个抽象的Clone()方法,并强制要求所有的派生类实现它。

这时候,我们需要定义一种方式,使派生类可以创建基类成员的副本。这可以通过定义一个protected的复制构造器来实现:

class BaseType

{

private string _label;

private int [] _values;

protected BaseType( )

{

    _label = "class name";

    _values = new int [ 10 ];

}

// 供派生类用来做clone。

protected BaseType( BaseType right )

{

    _label = right._label;

    _values = right._values.Clone( ) as int[ ] ;

}

}

sealed class Derived : BaseType, ICloneable

{

private double [] _dValues = new double[ 10 ];

public Derived ( )

{

    _dValues = new double [ 10 ];

}

// 使用基类的“复制构造器”构造一个副本。

private Derived ( Derived right ) :

    base ( right )

{

    _dValues = right._dValues.Clone( )

      as double[ ];

}

static void Main( string[] args )

{

    Derived d = new Derived();

    Derived d2 = d.Clone() as Derived;

    if ( d2 == null )

      Console.WriteLine( "null" );

}

public object Clone()

{

    Derived rVal = new Derived( this );

    return rVal;

}

}

在上面的代码中,我们的基类BaseType没有实现ICloneable接口,但它提供了一个受保护的复制构造器,以使派生类可以复制其内的成员。如果有必要,“叶子类”——即那些密封类——可以实现ICloneable接口。我们的基类没有强制要求所有的派生类实现ICloneable接口,但它为所有希望实现ICloneable接口的派生类提供了必要的方法支持。

ICloneable接口有其价值所在,但那都是特例,而非普遍的规则。对于值类型来讲,我们永远都不需要支持ICloneable接口,使用默认的赋值操作就可以了。我们应该为那些确实需要复制操作的“叶子类”提供ICloneable接口支持。对于那些子类可能需要支持ICloneable接口的基类,我们应该为其创建一个受保护的复制构造器。除此之外,我们应该避免支持ICloneable接口

 

WinCC 7.5 读取 SQL server2016 中的表格数据 环境 win10 SQL Server 2016 WinCC V7.5 SP2 1 安装SQL Server 2016 2 选择服务器名称 .\WINCC 3 建数据库 阅读详情

相关推荐

自抗扰控制(ADRC)理论工程实践:8.1 自适应ADRC参数在线整定

自适应自抗扰控制(AADRC)针对传统固定参数ADRC在动态变化系统中的局限性,提出通过在线调整关键参数(如观测器带宽ω₀、控制器带宽ω_c)以适应对象动态变化。主要方法包括基于稳定性理论的自适应律设计和基于性能指标的优化调节,前者保证闭环稳定但设计复杂,后者通过梯度搜索或模糊规则实现性能优化但缺乏严格稳定性证明。当前挑战在于非线性时变系统的稳定性分析、参数变化速率限制及工程实现的计算负担。AADRC拓展了ADRC在变参数系统(如无人机、软体机器人)中的应用,是迈向自主智能控制的关键技术。

技术工作者 181

ICloneable和IComparable

对于所有面向对象的语言,复制永远是一个容易引发讨论的题目,C#中也不例外。此类问题在面试中极其容易被问到,我们应该在了解浅拷贝和深拷贝基本概念的基础上,从设计的角度进一步考虑如何支持对象的拷贝。

kalvin_y_liu的博客 896

在STM32F103RBT6微控制器上利用USB虚拟Com端口技术,高效实现ADC数据传输:详细操作步骤示例代码解析

以上就是在STM32F103RBT6上使用USB虚拟Com端口实现ADC数据传输的全部内容。虽然过程中有很多步骤和细节需要注意,但只要按照步骤来,理解每一段代码的作用,就完全可以掌握这个过程。在实际应用中,我们可能需要根据实际需要修改一些代码,如调整ADC的参数,改变数据的处理方式等。但是,只要理解了这个过程,我们就可以很灵活地进行修改。希望这篇文章对你有所帮助。如果你有任何疑问,欢迎在评论区留言,我会尽我所能进行解答。

qq_38334677的博客 1144

C# ICloneable的特点及其用法

C#中,ICloneable是一个接口,用于定义允许一个对象创建自身的精确副本,即“克隆”的能力。ICloneableClone,该方法在实现时应该返回当前对象的一个副本。这里是ICloneable

琅嬛福地 1587

c#的System.ICloneable接口说明

System.ICloneable接口支持克隆,即用现有实例相同的值创建类的新实例。msdn上的解释很简单,主要就是clone方法的实行,介绍深拷贝和浅拷贝,搞的很糊涂,那么到底是什么意思呢?看看下面的原理可能就会明白很多了。引自http://www.cnblogs.com/anderslly/archive/2007/04/08/implementingcloneabletype.html

halon博客 1171

C#ICloneable深复制浅复制

C#ICloneable深复制浅复制

wangnaisheng的专栏 592

[c#基础]-ICloneable

什么是浅拷贝深拷贝? 浅拷贝 将对象的字段复制到新的对象副本中,同时将字段的值也复制过去,但引用类型值复制引用,而不是引用类型本身,也就是,如果源对象的引用类型的字段的值改变了,拷贝的对象的对应的引用类型的字段也会跟着变化。 深拷贝 将对象的字段复制到新的对象副本中,无论是值类型还是引用类型的字段,都会复制类型本身及值。但,源对象的值变化,并不会影响副本中的对应的值。 浅拷...

一个记录自己技术成长的博客 2097

ICloneable 接口--c# 深复制浅复制

支持克隆,即用现有实例相同的值创建类的新实例。 命名空间: System 程序集: mscorlib(在 mscorlib.dll 中) 语法 [ComVisibleAttribute(true)]public interface ICloneable ICloneable 接口包含一个成员 Clone,它用于支持除 MemberwiseClone 所提供的克隆之外的...

angyunyao1518的博客 330

对象的复制:浅复制深复制ICloneable接口

所谓的“对象的复制” 即生成一个指定对象“一模一样”的“同胞兄弟”。 对于对象的复制,有浅复制深复制两种情况。 1、 浅复制:是指当对象的字段值被复制时,字段引用的对象不会被复制。 例如,如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个浅复制,那麽两个对象将引用同一个字符串。 2、 深复制:是对对象事例中字段引用的对象也进行复制的一种方式。 例如,如果一个对象...

weixin_33778778的博客 97

C#编程之ICloneable 接口--c# 深复制浅复制

支持克隆,即用现有实例相同的值创建类的新实例。命名空间:  System 程序集:  mscorlib(在 mscorlib.dll 中)语法C# [ComVisibleAttribute(true)]public interface ICloneableICloneable 接口包含一个成员 Clone,它用于支持除 Memberwi

mylady的专栏 1896

浅复制 深复制

(1)浅复制:复制一个对象的时候,仅仅复制原始对象中所有的非静态类型成员和所有的引用类型成员的引用。(新对象和原对象将共享所有引用类型成员的实际对象)(2)深复制:复制一个对象的时候,不仅复制所有非静态类型成员,还要复制所有引用类型成员的实际对象。

Kaizen的博客 276

.NET中深复制浅复制

概述: 在.NET里面,提供对象复制的功能,前提是实现ICloneable接口。ICloneable接口中有一个Clone方法, 可以在类中覆写实现自定义的拷贝方法。对象复制的实现方法有两种:深复制浅复制深复制浅复制:          浅复制浅复制是指源对象复制出来的对象共用一份实体,对其中任何一个对象的改动都会影响另外一个对象。相当于复制了指针。         深复

卓尔游侠 2197

ICloneable 接口 深拷贝 浅拷贝

支持克隆,即用现有实例相同的值创建类的新实例。 命名空间:  System 程序集:  mscorlib(在 mscorlib.dll 中) 语法 C# [ComVisibleAttribute(true)]public interface ICloneabl

andycode的专栏 583

C# Tips: ICloneable<T>

问题的提出 C#ICloneable是一个非常糟糕的设计,原因有两个: (1) 它没有实现ICloneable (2) 它没有区分深拷贝(deep copy)浅拷贝(shallow copy)。 那么,我们现在就定义一个ICloneable出来。 解决方案 ICloneable namespace Saturn.CommonLibrary.Infrastr

辛亚平的专栏 3389

c#学习摘录:类\继承\接口\字段、方法、属性\浅深复制(3)

深复制: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 控制台 { public class 复制内容 { public int 对象值;} //class深复制

浤济的专栏 356

实现ICloneable接口

实现ICloneable接口完成简历的原型实现 简历原型 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ResumeModel { class Resume : ICloneable ...

qq_39691716的博客 499

.net平台下深拷贝和浅拷贝(实现ICloneable接口的基础上)

在.net类库中,对象克隆广泛存在于各种类型的实现中,凡是实现了ICloneable接口的类型都具备克隆其对象实例的能力。所以本文讲述的深拷贝和浅拷贝也是在实现ICloneable接口的基础上进行的。 基本概念: 浅拷贝:指对象的字段被拷贝,而字段引用的对象不会被拷贝,拷贝对象和原对象仅仅是引用名称有所不同,但是它们共用一份实体。对任何一个对象的改变,都会影响到另外一个对象。大部分的引用类型,...

u012110480的专栏 731

ICloneable接口 Clone 深拷贝 浅拷贝

需要字段本身也实现了深拷贝Clone。应用场景不多,意义不大。 1. 隐含式地要求其子类和引用类也要实现ICloneable接口,如果引用层次比较深类似一个网状或树形接口,增加复杂性。 2. 考虑给sealed class实现ICloneable。 3. 值类型或者全都是简单值类型的引用对象用赋值可以应付大部分场景。 转载于:https://www.cnblogs.com/dir...

weixin_30747253的博客 195

Apple Configurator 2.zip

Apple Configurator 2 mac版安装,免App Store登录安装Apple Configurator 2 ,网络不好可以到这里下载,直接解压可用

SPSS 20.0 和 17.0 & 教程 下载地址

SPSS 20.0 和 17.0 & 教程 下载地址文档集成了SPSS 20.0 和 17.0 & 教程 的下载地址,

上一篇: C#集合类(HashTable, Dictionary, ArrayList)与HashTable线程安全
下一篇: C# 类型系统
Evan_Born
博客等级 码龄18年 5粉丝 16原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值