ArcObjects Library Reference  

ClonableObjClass

About the Clonable object Sample

[C#]

ClonableObjClass.cs

using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Collections;

using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.Geometry;

namespace ClonableObject
{
  /// <summary>
  /// This call demonstrated an implementation of a hybrid colnable
  /// class which has both .NET members as well as COM members.
  /// </summary>
  [Guid(ClonableObjClass.GUID)]
  [ClassInterface(ClassInterfaceType.None)]
  [ProgId("ClonableObject.ClonableObjClass")]
  public sealed class ClonableObjClass : IClone
  {
    #region different types of class members (COM and .NET)
    public const string GUID = "0678ecf9-4066-4a61-94fb-45d6c4753826";

    private int m_version = 1;
    private ISpatialReference m_spatialRef = null;
    private IPoint m_point = null;
    private string m_name = string.Empty;
    private ArrayList m_arr = null;
    private Guid m_ID;
    #endregion

    #region class constructor
    public ClonableObjClass()
    {
      m_ID = Guid.NewGuid();

      m_spatialRef = new UnknownCoordinateSystemClass();
    }
    #endregion

    #region public class properties
    public string Name
    {
      get { return m_name; }
      set { m_name = value; }
    }

    public int Version
    {
      get { return m_version; }
    }

    public ISpatialReference SpatialReference
    {
      get { return m_spatialRef; }
      set { m_spatialRef = value; }
    }

    public Guid ID
    {
      get { return m_ID; }
    }

    public IPoint Point
    {
      get { return m_point; }
      set { m_point = value; }
    }

    public ArrayList ManagedArray
    {
      get { return m_arr; }
      set { m_arr = value; }
    }
    #endregion

    #region IClone Members

    /// <summary>
    /// Assigns the properties of src to the receiver.
    /// </summary>
    /// <param name="src"></param>
    public void Assign(IClone src)
    {
      //1. make sure that src is pointing to a valid object
      if (null == src)
      {
        throw new COMException("Invalid objact.");
      }

      //2. make sure that the type of src is of type 'ClonableObjClass'
      if (!(src is ClonableObjClass))
      {
        throw new COMException("Bad object type.");
      }

      //3. assign the properties of src to the current instance
      ClonableObjClass srcClonable = (ClonableObjClass)src;
      m_name = srcClonable.Name;
      m_version = srcClonable.Version;
      m_ID = new Guid(srcClonable.ID.ToString());

      //don't clone the spatial reference, since in this case we want both object to 
      //reference the same spatial reference (for example like features in a featureclass 
      //which share the same spatial reference)
      m_spatialRef = srcClonable.SpatialReference;

      //clone the point. Use deep cloning 
      if (null == srcClonable.Point)
        m_point = null;
      else
      {
        IObjectCopy objectCopy = new ObjectCopyClass();
        object obj = objectCopy.Copy((object)srcClonable.Point);
        m_point = (IPoint)obj;
      }

      m_arr = (ArrayList)srcClonable.ManagedArray.Clone();
    }

    /// <summary>
    /// Clones the receiver and assigns the result to clonee.
    /// <returns></returns>
    public IClone Clone()
    {
      //create a new instance of the object
      ClonableObjClass obj = new ClonableObjClass();
      //assign the properties of the new object with the current object's properties.
      //according to each 'Ref' property, the user need to decide whether to use deep cloning
      //or shallow cloning. 
      obj.Assign(this);

      return (IClone)obj;
    }

    /// <summary>
    /// Returns TRUE when the receiver and the other object have the same properties.
    /// </summary>
    /// <param name="other"></param>
    /// <returns></returns>
    public bool IsEqual(IClone other)
    {
      //1. make sure that the 'other' object is pointing to a valid object
      if (null == other)
        throw new COMException("Invalid objact.");

      //2. verify the type of 'other'
      if (!(other is ClonableObjClass))
        throw new COMException("Bad object type.");

      ClonableObjClass otherClonable = (ClonableObjClass)other;

      //test that all ot the object's properties are the same.
      //please note the usage of IsEqual when using arcobjects components that
      //supports cloning
      if (otherClonable.Version == m_version &&
        otherClonable.Name == m_name &&
        otherClonable.ID == m_ID &&
        otherClonable.ManagedArray == m_arr &&
        ((IClone)otherClonable.SpatialReference).IsEqual((IClone)m_spatialRef) &&
        ((IClone)otherClonable.Point).IsEqual((IClone)m_point))

        return true;
    
      return false;
    }

    public bool IsIdentical(IClone other)
    {
      //1. make sure that the 'other' object is pointing to a valid object
      if (null == other)
        throw new COMException("Invalid objact.");

      //2. verify the type of 'other'
      if (!(other is ClonableObjClass))
        throw new COMException("Bad object type.");

      //3. test if the other is the 'this'
      if ((ClonableObjClass)other == this)
        return true;

      return false;
    }

    #endregion
  }
}

[Visual Basic .NET]

ClonableObjClass.vb

Imports Microsoft.VisualBasic
Imports System
Imports System.Text
Imports System.Runtime.InteropServices
Imports System.Collections

Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.SystemUI
Imports ESRI.ArcGIS.Geometry

  ''' <summary>
  ''' This call demonstrated an implementation of a hybrid colnable
  ''' class which has both .NET members as well as COM members.
  ''' </summary>
<Guid(ClonableObjClass.GUIDVAL), ClassInterface(ClassInterfaceType.None), ProgId("ClonableObject.ClonableObjClass")> _
Public NotInheritable Class ClonableObjClass
  Implements IClone
#Region "different types of class members (COM and .NET)"

  Public Const GUIDVAL As String = "0678ecf9-4066-4a61-94fb-45d6c4753826"

  Private m_version As Integer = 1
  Private m_spatialRef As ISpatialReference = Nothing
  Private m_point As IPoint = Nothing
  Private m_name As String = String.Empty
  Private m_arr As ArrayList = Nothing
  Private m_ID As Guid
#End Region

#Region "class constructor"
  Public Sub New()
    m_ID = Guid.NewGuid()

    m_spatialRef = New UnknownCoordinateSystemClass()
  End Sub
#End Region

#Region "public class properties"
  Public Property Name() As String
    Get
      Return m_name
    End Get
    Set(ByVal value As String)
      m_name = value
    End Set
  End Property

  Public ReadOnly Property Version() As Integer
    Get
      Return m_version
    End Get
  End Property

  Public Property SpatialReference() As ISpatialReference
    Get
      Return m_spatialRef
    End Get
    Set(ByVal value As ISpatialReference)
      m_spatialRef = value
    End Set
  End Property

  Public ReadOnly Property ID() As Guid
    Get
      Return m_ID
    End Get
  End Property

  Public Property Point() As IPoint
    Get
      Return m_point
    End Get
    Set(ByVal value As IPoint)
      m_point = value
    End Set
  End Property

  Public Property ManagedArray() As ArrayList
    Get
      Return m_arr
    End Get
    Set(ByVal value As ArrayList)
      m_arr = value
    End Set
  End Property
#End Region

#Region "IClone Members"

  ''' <summary>
  ''' Assigns the properties of src to the receiver.
  ''' </summary>
  ''' <param name="src"></param>
  Public Sub Assign(ByVal src As IClone) Implements IClone.Assign
    '1. make sure that src is pointing to a valid object
    If Nothing Is src Then
      Throw New COMException("Invalid objact.")
    End If

    '2. make sure that the type of src is of type 'ClonableObjClass'
    If Not (TypeOf src Is ClonableObjClass) Then
      Throw New COMException("Bad object type.")
    End If

    '3. assign the properties of src to the current instance
    Dim srcClonable As ClonableObjClass = CType(src, ClonableObjClass)
    m_name = srcClonable.Name
    m_version = srcClonable.Version
    m_ID = New Guid(srcClonable.ID.ToString())

    'don't clone the spatial reference, since in this case we want both object to 
    'reference the same spatial reference (for example like features in a featureclass 
    'which share the same spatial reference)
    m_spatialRef = srcClonable.SpatialReference

    'clone the point. Use deep cloning 
    If Nothing Is srcClonable.Point Then
      m_point = Nothing
    Else
      Dim objectCopy As IObjectCopy = New ObjectCopyClass()
      Dim obj As Object = objectCopy.Copy(CObj(srcClonable.Point))
      m_point = CType(obj, IPoint)
    End If

    m_arr = CType(srcClonable.ManagedArray.Clone(), ArrayList)
  End Sub

  ''' <summary>
  ''' Clones the receiver and assigns the result to clonee.
  ''' <returns></returns>
  Public Function Clone() As IClone Implements IClone.Clone
    'create a new instance of the object
    Dim obj As ClonableObjClass = New ClonableObjClass()
    'assign the properties of the new object with the current object's properties.
    'according to each 'Ref' property, the user need to decide whether to use deep cloning
    'or shallow cloning. 
    obj.Assign(Me)

    Return CType(obj, IClone)
  End Function

  ''' <summary>
  ''' Returns TRUE when the receiver and the other object have the same properties.
  ''' </summary>
  ''' <param name="other"></param>
  ''' <returns></returns>
  Public Function IsEqual(ByVal other As IClone) As Boolean Implements IClone.IsEqual
    '1. make sure that the 'other' object is pointing to a valid object
    If Nothing Is other Then
      Throw New COMException("Invalid objact.")
    End If

    '2. verify the type of 'other'
    If Not (TypeOf other Is ClonableObjClass) Then
      Throw New COMException("Bad object type.")
    End If

    Dim otherClonable As ClonableObjClass = CType(other, ClonableObjClass)

    'test that all ot the object's properties are the same.
    'please note the usage of IsEqual when using arcobjects components that
    'supports cloning
    If otherClonable.Version = m_version AndAlso otherClonable.Name = m_name AndAlso otherClonable.ID = m_ID AndAlso otherClonable.ManagedArray Is m_arr AndAlso (CType(otherClonable.SpatialReference, IClone)).IsEqual(CType(m_spatialRef, IClone)) AndAlso (CType(otherClonable.Point, IClone)).IsEqual(CType(m_point, IClone)) Then

      Return True
    End If

    Return False
  End Function

  Public Function IsIdentical(ByVal other As IClone) As Boolean Implements IClone.IsIdentical
    '1. make sure that the 'other' object is pointing to a valid object
    If Nothing Is other Then
      Throw New COMException("Invalid objact.")
    End If

    '2. verify the type of 'other'
    If Not (TypeOf other Is ClonableObjClass) Then
      Throw New COMException("Bad object type.")
    End If

    '3. test if the other is the 'this'
    If CType(other, ClonableObjClass) Is Me Then
      Return True
    End If

    Return False
  End Function

#End Region
End Class