I'm trying to make a Node Based editor with C# and Dataflow. I created the following class for the nodes:
public interface INode
{
public int Id {get; set;}
public string Name {get; set;}
}
public class Node<TInput, TOutput> : INode
{
public string Name {get; private set;}
public int Id {get; set;}
public IPropagatorBlock<TInput, TOutput> NodeBlock {get; protected set;}
public Node(string Name, int Id) {
this.Name = Name;
this.Id = Id;
}
}
Then I have the classes that derive from the class Node:
public class ThresholdNode : Node<int, float>
{
public ThresholdNode(string Name, int Id) : base(Name, Id)
{
NodeBlock = CreateNodeBlock();
}
private IPropagatorBlock<int, float> CreateNodeBlock() {
return new TransformBlock<int, float>(...);
}
}
And then there's the Node Manager, that's responsible for managing the nodes. The node manager stores all the created nodes inside the following generic list:
public List<INode> NodeList
Since the nodes can have different Input and Output types, I can't put the NodeBlock inside the INode
interface. So here's where I'm stuck. I want to make a function inside the NodeManager class that connects two nodes. If I'd know the type of them, I could do the following:
public void ConnectNodes(int originIndex, int destinationIndex) {
var originNodeBlock = NodeList[originIndex] as IPropagatorBlock<int, float>;
var destinationNodeBlock = NodeList[destinationIndex] as IPropagatorBlock<float, string>
originNodeBlock.LinkTo(destinationNodeBlock);
}
But since I don't know what types are their Inputs and Outputs, I can't cast them. I also tried to do it using the dynamic
thing, but it threw an exception at runtime, and I believe it had something to do with Dataflow, though I'd like to be proved wrong on that. Here's how I tried to do it using dynamic
:
First I created a method on the NodeClass to return the NodeBlock and added the same method to the INode interface:
public interface INode {
...
public dynamic GetNodeBlock();
}
public class Node<TInput, TOutput> : INode {
...
public dynamic GetNodeBlock() {
return this.NodeBlock;
}
}
Then, in the NodeManager class I wrote the following method for connecting the nodes:
public bool ConnectNodes(int originIndex, int destinationIndex) {
INode originNode = NodeList[originIndex];
INode destinationNode = NodeList[destinationIndex];
var originNodeBlock = originNode.GetNodeBlock();
var destinationNodeBlock = originNode.GetNodeBlock();
originNodeBlock.LinkTo(destinationNodeBlock); // <--- throws exception here
return true;
}
However, at runtime the LinkTo throws the following exception:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'No overload for method 'LinkTo' takes 1 arguments'