Click or drag to resize

DefinitionalObjectClone Method

Clones this object using the specified context.

Namespace:  AGI.Foundation.Infrastructure
Assembly:  AGI.Foundation.Core (in AGI.Foundation.Core.dll) Version: 24.2.419.0 (24.2.419.0)
Syntax
public abstract Object Clone(
	CopyContext context
)

Parameters

context
Type: AGI.Foundation.InfrastructureCopyContext
The context to use to perform the copy.

Return Value

Type: Object
A new instance which is a copy of this object.

Implements

ICloneWithContextClone(CopyContext)
Remarks

This method should be implemented to call a copy constructor on the class of the object being cloned. The copy constructor should take the CopyContext as a parameter in addition to the existing instance to copy. The copy constructor should first call AddObjectMappingT(T, T) to identify the newly constructed instance as a copy of the existing instance. It should then copy all fields, using UpdateReferenceT(T) to copy any reference fields.

A typical implementation of ICloneWithContext:

C#
public class MyClass : ICloneWithContext
{
    public MyClass(MyClass existingInstance, CopyContext context)
    {
        context.AddObjectMapping(existingInstance, this);
        someReference = context.UpdateReference(existingInstance.someReference);
    }

    public object Clone(CopyContext context)
    {
        return new MyClass(this, context);
    }

    private object someReference;
}

In general, all fields that are reference types should be copied with a call to UpdateReferenceT(T). There are a couple of exceptions:

  1. Fields that are aggregate parts of the object should always be copied. A referenced object is an aggregate if properties or methods on the object being copied can modify the externally-visible value of the referenced object.
  2. If the semantics of the referenced object require that it have a single parent, owner, context, etc., and the object being copied is that parent, owner, or context, then the referenced object should always be copied.

If one of these exceptions applies, the CopyContext should be given an opportunity to update the reference before the reference is copied explicitly. Use UpdateReferenceT(T) to update the reference. If UpdateReferenceT(T) returns the original object, indicating that the context does not have a replacement registered, then copy the object manually by invoking a Clone method, a copy constructor, or by manually constructing a new instance and copying the values.

C#
alwaysCopy = context.UpdateReference(existingInstance.alwaysCopy);
if (existingInstance.alwaysCopy != null &&
    ReferenceEquals(alwaysCopy, existingInstance.alwaysCopy))
{
    alwaysCopy = existingInstance.alwaysCopy.Clone(context) as AlwaysCopy;
}

If you are implementing an evaluator (a class that implements IEvaluator), the UpdateEvaluatorReferences(CopyContext) method shares some responsibilities with the copy context constructor. Code duplication can be avoided by doing the following:

  1. For references to other evaluators ONLY, simply assign the reference in the constructor instead of calling UpdateReferenceT(T). You should still call UpdateReferenceT(T) on any references to non-evaluators.
  2. Call UpdateEvaluatorReferences(CopyContext) as the last line in the constructor and pass it the same CopyContext passed to the constructor.
  3. Implement UpdateEvaluatorReferences(CopyContext) as normal. See the reference documentation for UpdateEvaluatorReferences(CopyContext) for more information on implementing that method.
C#
public MyClass(MyClass existingInstance, CopyContext context)
    : base(existingInstance, context)
{
    someReference = context.UpdateReference(existingInstance.someReference);
    evaluatorReference = existingInstance.evaluatorReference;
    UpdateEvaluatorReferences(context);
}

public override void UpdateEvaluatorReferences(CopyContext context)
{
    evaluatorReference = context.UpdateReference(evaluatorReference);
}

public override object Clone(CopyContext context)
{
    return new MyClass(this, context);
}

private object someReference;
private IEvaluator evaluatorReference;
See Also