Class ChangeDag<TNode, TIdentifier, TVisitor>
Generic base class for logic around modifying immutable nodes in a directed acyclic graph, propagating any changes up the dependency tree. This allows "change X" logic to be shared across Expression and Table classes.
Inherited Members
Namespace: Mangrove.MetricSetTransformers.Utilities
Assembly: MetricSetTransformers.dll
Syntax
public abstract class ChangeDag<TNode, TIdentifier, TVisitor>
where TNode : class, ICloneable<TNode>, IVisitable<TVisitor> where TIdentifier : class
Type Parameters
Name | Description |
---|---|
TNode | The base type of node to be changed. Probably either Table or Expression. |
TIdentifier | The type of a node's "identifier", e.g. String for Table nodes and Table for Expression nodes. |
TVisitor | Type of visitor that nodes accept. Note: any subclass must implement
this type. Sadly, this cannot be expressed as a type constraint because C# only
allows constraints of the form |
Constructors
View SourceChangeDag()
Declaration
public ChangeDag()
Properties
View SourceMapping
Declaration
protected IDictionary<TNode, TNode> Mapping { get; }
Property Value
Type | Description |
---|---|
IDictionary<TNode, TNode> |
Methods
View SourceChangeIdentifier(TNode)
Override this to change the identifier node
has.
Declaration
protected virtual TIdentifier ChangeIdentifier(TNode node)
Parameters
Type | Name | Description |
---|---|---|
TNode | node |
Returns
Type | Description |
---|---|
TIdentifier |
Identifier(TNode)
Non-unique "identifier" that node
has.
Declaration
protected abstract TIdentifier Identifier(TNode node)
Parameters
Type | Name | Description |
---|---|---|
TNode | node |
Returns
Type | Description |
---|---|
TIdentifier |
ReplaceParent(TNode, TNode, TNode)
Override this to replace newParent
, given the
information of oldNode
and newNode
.
Declaration
protected virtual TNode ReplaceParent(TNode oldNode, TNode newNode, TNode newParent)
Parameters
Type | Name | Description |
---|---|---|
TNode | oldNode | |
TNode | newNode | |
TNode | newParent |
Returns
Type | Description |
---|---|
TNode |
Reset()
Clear the internal state.
Declaration
public void Reset()
UberVisit<TSubnode>(TSubnode, Func<TSubnode, TNode>)
Another version of "uber visit" with fewer type parameters,
when the node's identifier has the same type as the "generic"
node type TNode
.
Declaration
protected void UberVisit<TSubnode>(TSubnode node, Func<TSubnode, TNode> change)
where TSubnode : TNode, ICloneable<TSubnode, TIdentifier, TNode>
Parameters
Type | Name | Description |
---|---|---|
TSubnode | node | |
Func<TSubnode, TNode> | change |
Type Parameters
Name | Description |
---|---|
TSubnode |
UberVisit<TSubnode, TSubidentifier>(TSubnode, Func<TSubnode, TNode>)
"Master" visit function containing the core logic for doing nothing if a node has already been visited, visiting all its direct parents, replacing the identifier or any parents if needed, and finally changing the node itself. This removes nearly all boilerplace from the individual "visit" methods in ChangeExpressions and ChangeTables.
Declaration
protected void UberVisit<TSubnode, TSubidentifier>(TSubnode node, Func<TSubnode, TNode> change)
where TSubnode : TNode, ICloneable<TSubnode, TSubidentifier, TNode> where TSubidentifier : class, TIdentifier
Parameters
Type | Name | Description |
---|---|---|
TSubnode | node | The node being visited. |
Func<TSubnode, TNode> | change | The "change" function for |
Type Parameters
Name | Description |
---|---|
TSubnode | Type of the (directed acyclic graph) node being visited. |
TSubidentifier | Type of the identifier that |
Operators
View SourceImplicit(ChangeDag<TNode, TIdentifier, TVisitor> to TVisitor)
Since we require that any concrete subclass implement TVisitor
,
define an implicit conversion of this class to that type.
Declaration
public static implicit operator TVisitor(ChangeDag<TNode, TIdentifier, TVisitor> changeDag)
Parameters
Type | Name | Description |
---|---|---|
ChangeDag<TNode, TIdentifier, TVisitor> | changeDag |
Returns
Type | Description |
---|---|
TVisitor |
Remarks
The intermediate cast to Object is needed because the C#
compiler can't guarantee that this is a TVisitor
. See:
https://stackoverflow.com/q/7978316 .