Bidirectional connected between to C# classes - c#

I'm currently working on project (for fun) that involves simulating logic gates. I have a Connection.cs and a Gate.cs that is the parent of other classes like Not, And, Or, etc. In my Gate class I have an abstract method Evaluate that will end up doing the work with inputs and setting outputs.
public abstract class Gate : IConnectable {
private int[] inputs;
private int[] outputs;
protected Gate(int inputCount, int outputCount) {
inputs = new int[inputCount];
outputs = new int[outputCount];
}
...
public abstract void Evaluate();
}
public class Connection {
private IConnectable input;
private IConnectable output;
public Connection(IConnectable from, IConnectable to) {
input = from;
output = to;
}
}
In the end, I am trying to figure out a concise way to have a Gate object contain references to its connections that are inputs/outputs and to have the Connections know what is on either end of the "wire". Is there an easy way to do this?

Generally you want some way to represent a graph. There are many ways to do that.
I would consider a design like this as a starting point:
interface IGate
{
bool Value { get; }
}
class And : IGate
{
public IGate X { get; private set; }
public IGate Y { get; private set; }
public bool Value
{
get
{
return X.Value && Y.Value;
}
}
public And(IGate x, IGate y)
{
X = x;
Y = y;
}
}
class Input : IGate
{
public bool Value { get; set; }
public Input(bool value)
{
Value = value;
}
}
An example is:
new And(new Input(true), new And(new Input(true), new Input(false))).Value

I usually do something like this
public class Node {
private static List<Node> nodes = new List<Node>();
private List<Node> inputs { get; set;}
private List<Node> outputs {get;set;}
protected Node() { }
protected Node(Node input, Node outPut) {
Node newNode = new Node();
nodes.Add(newNode);
newNode.inputs.Add(input);
newNode.outputs.Add(output);
}
}

Related

Check if instance of class exists with certain property

I have a list of classes, each with four properties:
public class BroncoClass
{
public NPC npc { get; set; }
public int TimeLeft { get; set; }
public bool Gravity { get; set; }
public bool Rotation { get; set; }
}
public List<BroncoClass> BroncoList = new List<BroncoClass>();
I want to check if the list contains a class with a specific npc value, for example:
for (int i = 0; i < Main.npc.Length; i++) // For every alive npc
{
if(BroncoList.contains a class where npc == Main.npc[i])
{
}
}
Haven't been able to find an answer online, any help is appreciated.
The real solution is to just keep a collection somewhere and use LINQ to query it. Presumably this collection would be easy to maintain as it would be the collection that is used for all other operations with BroncoClass.
After update to OP...
You already have the list, just use list.Any(o => o.npc == testNpc) or whatever other predicate you may need.
However, if you really want to do the actual question:
Sounds like a reasonable usage of a factory pattern; but you will need to effectively do manual memory management. Your factory would be something like:
// Could be static, but I hate static. Don't use static.
public class BroncoFactory
{
private List<BroncoClass> trackedObjects = new List<BroncoClass>();
public BroncoClass New()
{
var newInstance = new BroncoClass();
trackedObjects.Add(newInstance)
}
// Don't forget to call this or you'll leak!
public void Free(BroncoClass instance)
{
trackedObjects.Remove(instance);
}
public bool ExistsWithNPC(NPC test)
{
return trackedObjects.Any(o => o.npc == test);
}
}
Just really, really don't forget to call Free on an object when you are done with it.
Very similar to #BradleyDotNET's answer. I just folded the factory into the class as static methods. I'm not saying this is right way to go, I'm just offering it as a solution to your question. Using static methods in the class seems closer to what the OP is asking about.
First, I needed an NPC class to get this to compile. Notice that it implements IEquatable so that I can compare instances for equality the way I want to (and that I override GetHashCode because that's a requirement).
public class NPC : IEquatable<NPC>
{
private static int _indexKeeper = 0;
public int Index { get; } = _indexKeeper++;
public bool Equals(NPC other)
{
return Index == other?.Index;
}
public override int GetHashCode()
{
return Index.GetHashCode();
}
}
With that, here's the BroncoClass (mostly untested):
public class BroncoClass
{
private BroncoClass(int timeLeft, bool gravity, bool rotation)
{
Npc = new NPC();
TimeLeft = timeLeft;
Gravity = gravity;
Rotation = rotation;
}
public NPC Npc { get; set; }
public int TimeLeft { get; set; }
public bool Gravity { get; set; }
public bool Rotation { get; set; }
private static List<BroncoClass> _instances = new List<BroncoClass>();
public static BroncoClass Create(int timeLeft, bool gravity, bool rotation)
{
var bronco = new BroncoClass(timeLeft, gravity, rotation);
_instances.Add(bronco);
return bronco;
}
public static bool Remove(NPC npc)
{
var broncoFound = _instances.FirstOrDefault(b => b.Npc == npc);
if (broncoFound == null)
{
return false;
}
_instances.Remove(broncoFound);
return true;
}
public static BroncoClass Find(NPC npc)
{
return _instances.FirstOrDefault(b => b.Npc == npc);
}
}

C# generic, where T class : (inheritance class)

I have two type of nodes, one is MyLinkNode it's used as base, another one is GraphNode which inheritance MyLinkNode.
I try to create MyQueue with MyLinkNode. Everything is OK until I try to add GraphNode to MyQueue. I can't use MyQueue with GraphNode since it's bigger.
An alternative way is create another queue for GraphNode, but that means I would need to create lots of class if I have more type of nodes.
Is there any suggestion?
public class MyQueue<T> where T : MyLinkNode<T>
{
private T Head;
private T Last;
public MyQueue(){ ... }
public void Enqueue(T item)
{
item.Prev = Last;
Last.Next = item;
Last = item;
}
}
public class MyGraphQueue
{
//everything is the same with MyQueue besides the Node Type
//I don't want to create like this.
private GraphNode Head;
private GraphNode Last;
public MyGraphQueue(){ ... }
public void Enqueue(GraphNode item)
{
item.Prev = Last;
Last.Next = item;
Last = item;
}
}
public class MyLinkNode<T>
{
public T data { get; set; }
public MyLinkNode<T> Next { get; set; }
public MyLinkNode<T> Prev { get; set; }
}
public class GraphNode<T> : MyLinkNode<T>
{
public GraphNode()
{
this.adjacencyNodes = new List<GraphNode<T>>();
this.isVisited = false;
}
public List<GraphNode<T>> adjacencyNodes;
public bool isVisited { get; set; }
}
public void BFS<T>(GraphNode<T> v)
{
MyQueue<GraphNode<T>> queue = new MyQueue<GraphNode<T>>(); // error, can't implicit convert GraphNode to MyLinkNode<T>
MyGraphQueue queue = new MyGraphQueue(); //It's how I do now.
}
This is a standard Generics inheritance problem. You need to separate what the Queue needs from the generic type. Just add another base class for the queue constraint.
This will keep the queue to have the guarantee of all items having type T and not require extra types or multiple class definitions for all of the concrete types. Eric Lippert has a good article here on why this limitation was required in the generics system.
public class CallingClass
{
public void BFS(GraphNode v)
{
MyQueue<GraphNode> queue = new MyQueue<GraphNode>(); // error, can't implicit convert GraphNode to MyLinkNode<T>
// MyGraphQueue queue = new MyGraphQueue(); //It's how I do now.
}
}
public class QueueItem
{
public QueueItem Next { get; set; }
public QueueItem Prev { get; set; }
}
public class MyQueue<T> where T : QueueItem
{
private T Head;
private T Last;
public MyQueue() { }
public void Enqueue(T item)
{
item.Prev = Last;
Last.Next = item;
Last = item;
}
}
public class MyLinkNode<T>: QueueItem
{
public T data { get; set; }
}
public class GraphNode : MyLinkNode<string>
{
public GraphNode()
{
this.adjacencyNodes = new List<GraphNode>();
this.isVisited = false;
}
public List<GraphNode> adjacencyNodes;
public bool isVisited { get; set; }
}
MyQueue<T> where T : MyLinkNode<T> cannot accept a MyLinkNode<string>
Beacuse here T is string. but, obviously string doesn't inherit from MyLinkNode
I think the solution is simpler than you imagine.
Just set the type (T) of the value in the queue, and inside use MyLinkNode<T>:
public class MyQueue<T>
{
private MyLinkNode<T> Head;
private MyLinkNode<T> Last;
public void Enqueue(MyLinkNode<T> item)
{
item.Prev = Last;
Last.Next = item;
Last = item;
}
}
public void BFS(GraphNode v)
{
MyQueue<string> queue = new MyQueue<string>(); // no error anymore
queue.Enqueue(v);
}
That's not surprising. You need
public class MyQueue<T, S> where T : MyLinkNode<S>
{
private T Head;
private T Last;
public MyQueue() { }
public void Enqueue(T item)
{
item.Prev = Last;
Last.Next = item;
Last = item;
}
}
public void BFS(GraphNode v)
{
MyQueue<GraphNode, string> queue = new MyQueue<GraphNode, string>();
}
The problem is coming from your first line.
Use:
public class MyQueue<T> where T : MyLinkNode<string> { }
Instead of:
public class MyQueue<T> where T : MyLinkNode<T> { }
and it will work fine.

Auto-properties with mutable objects

I'm trying to make properties for mutable objects. Is this a problem with Auto-properties? For example, the following code would allow for unwanted manipulation of the mutable object. How would I avoid this?
public class Mutable{
public int Value { get; set; }
}
public class ClassWithMutable{
public Mutable Object { get; }
public ClassWithMutable(){
this.mutable = new Mutable();
this.mutable.Value = 0;
}
}
public class Demo{
public static void Main(String[] args){
ClassWithMutable test = new ClassWithMutable();
Mutable o = test.Object;
o.Value = 1;
}
}
You could use an interface that only exposes the get of the properties, and a private class that implements it.
public interface IImmutable {
int Value { get; }
}
public class ClassWithImmutable{
private Mutable _object;
public IImmutable Object { get { return _object; } }
public ClassWithImmutable(){
this._object = new Mutable();
this._object.Value = 0;
}
private class Mutable : IImmutable {
public int Value { get; set; }
}
}
public class Demo{
public static void Main(String[] args){
ClassWithImmutable test = new ClassWithImmutable();
IImmutable o = test.Object;
o.Value = 1; // fails
}
}
I'm trying to understand the intent of your question rather than your question, and I'm coming up a little short. However, I think I came up with something.
You can "mask" your mutable object under a read-only interface.
public class ClassWithMutable
{
public IImumutable Mutable { get { return _mutable; } }
private Mutable _mutable;
public ClassWithMutable()
{
_mutable = new Mutable()
{
Value = 1
};
}
}
public interface IImumutable
{
int Value { get; }
}
public class Mutable : IImumutable
{
public int Value { get; set; }
}
As long as your ClassWithMutable instance exposes the Mutable instance as an Immutable then the consumer can't easily change it. (I emphasize easily, because there's pretty much always a way that you can change it. It just depends on how hard you want to work.)

Tree creation using generics in c#

I am new to c# i have just completed a huffman tree and now next step is to make it generic i mean this symbolshould work for every data type. Since i am c# beginner i need some basic idea to do that.
My huffman tree consists of 3 classes. Class huffman, node and MyClass(which contains the main function) where freq is the number of times the symbol repeats they are structured as given below:
namespace final_version_Csharp
{
public Class Huffman
{
public classNode
{
public Node next, left, right;
public int symbol;
public int freq;
}
public Node root;
}
public void huffman_node_processing()
{
//done the addition of two minimum freq here
}
public void GenerateCode(Node parentNode, string code)
{
//done the encoding work here
}
public class MyClass
{
public static void Main(string[] args)
{
Huffman ObjSym = new Huffman(args); //object creation by reading the data fron a file at sole argument
//All other methods are here
ObjSym.huffman_node_processing(); //this for adding the two minimum nodes
ObjSym.GenerateCode(ObjSym.root, ""); //this for encoding
}
}
}
Could some one please help me in making this "symbol" work for all data types like "short","long" etc.
If I am understanding you correctly, you would basically do something like
namespace final_version_Csharp
{
public Class Huffman<K> where K : IComparable<K>
{
public classNode<K>
{
public Node next, left, right;
public K symbol;
public int freq;
}
public Node root;
}
...
public class MyClass
{
public static void Main(string[] args)
{
Huffman ObjSym = new Huffman<int>();
//All other methods are here
ObjSym.huffman_node_processing(); //this for adding the two minimum nodes
ObjSym.GenerateCode(ObjSym.root, ""); //this for encoding
}
}
}
All you need to use here is an interface
public interface IMyType
{
int Symbol { get; set; }
int Freq { get; set; }
}
then just use this for all classes you want to be able to work with generically. So
public class ClassA : IMyType
{
...
public int Symbol { get; set; }
public int Freq { get; set; }
...
}
public class ClassB : IMyType
{
...
public int Symbol { get; set; }
public int Freq { get; set; }
...
}
Then you can use these object in methods like this
void SomeMethod(IMyType o)
{
o.Symbol = 1;
o.Freq = 2;
...
}
IMyType a = new ClassA();
IMyType b = new ClassB();
SomeMethod(a);
SomeMethod(b);
I hope this helps.

C# Modifying the return of a custom data type at runtime

I've been teaching myself C#, and I'm just learning how to use custom data types. The program I'm writing produces a bunch of pairs of coordinate pairs. I thought it'd be a neat idea to create a data type that holds each set (x1, x2, y1, y2), along with a few other variables pertaining to that set. However, the program will produce more than one array of coordinates sets (different categories), so keeping track of things was still difficult. I then broke it down further into categories, and placed each category under a third type that acts as a third level, which is then put into a list.
Each "tier" of items has some properties specific to that tier, but prior to this roadblock I didn't have any need to swap data among the hierarchy. The problem arose when I realized that I needed to modify the coordinate pair sets using an offset, and each offset is specific to the parent data type. I can modify the get{} code to return the data plus the offset (I called it "skew"), but not if the offset is from outside the data type's class itself. I tried setting a value in the parent data type (even a public static one), but the child couldn't read it for some reason.
The only way I know how to make this work is by setting the property in each coordinate set, but there could be thousands of them. The value is unique to the parent, but all the children need to use it, so that seems wasteful, given that there will be a lot of other calculations going on. My other thought was to maintain an offset array, and add it to the places where the values are retrieved. But, that isn't as clean as containing it within the data type itself, and so it will add to the confusion. Is there another method of accomplishing this?
Here is how some of the code looks:
public class SlotData
{
private double _x1, _x2, _y1, _y2;
public double X1
{
get { return _x1; }
set { _x1 = value; }
}
public double X2
{
get { return _x2; }
set { _x2 = value; }
}
public double Y1
{
get { return _y1; }
set { _y1 = value; }
}
public double Y2
{
get { return _y2; }
set { _y2 = value; }
}
}
public class ClientInfo
{
public static double _skewX, _skewY;
public SlotGroup1 Group1
{
get;
set;
}
public SlotGroup2 Group2
{
get;
set;
}
public SlotGroup3 Group3
{
get;
set;
}
}
public class SlotGroup1
{
public SlotData Slot1
{
get;
set;
}
public SlotData Slot2
{
get;
set;
}
}
public class SlotData
{
private SlotData() { }
public SlotData(SlotGroupBase group)
{
this._group = group;
}
private SlotGroupBase _group;
public double X1 { get; set; }
public double X2 {get; set;}
public double Y1 {get; set;}
public double Y2 {get; set;}
public double NewX1
{
get
{
return _group.ClientInfo._skewX + X1;
}
}
}
public class ClientInfo
{
public double _skewX, _skewY;
public SlotGroup1 Group1 { get; set; }
}
public abstract class SlotGroupBase
{
private SlotGroupBase() { }
public SlotGroupBase(ClientInfo ci)
{
this._ci = ci;
}
private ClientInfo _ci;
public ClientInfo ClientInfo
{
get
{
return _ci;
}
}
}
public class SlotGroup1 : SlotGroupBase
{
public SlotGroup1(ClientInfo ci):base (ci) {}
public SlotData Slot1 { get; set; }
public SlotData Slot2 { get; set; }
}
static void Main(string[] args)
{
ClientInfo ci = new ClientInfo();
SlotGroup1 sg1 = new SlotGroup1(ci);
sg1.Slot1 = new SlotData(sg1);
sg1.Slot2 = new SlotData(sg1);
Console.ReadLine();
}
In your code you don't have either parent or descendant data types. So, members of some type couldn't be accessible to other types in any way other than you will have reference to an instance of object of some type.
But object-oriented programming could help you. In case if each from SlotGroupN types must have reference to ClientInfo, it would be worthwhile to have base class SlotGroupBase which will contain reference to ClientInfo. Also you should add to SlotData type reference to SlotGroupBase. In this case you will access your skews like
return _group.ClientInfo._skewX + X1;
Another good idea is to restrict yourself and other developers from creation SlotGroupN class instances without reference to ClientInfo, SlotData class item without reference to SlotGroup. To achieve this you should make default constructors private and add constructor with parameter ClientInfo
public SlotGroupBase(ClientInfo ci)
Extending you design ...
using System.Drawing;
public class SlotData
{
private PointF _one;
private PointF _two;
internal SizeF Skew {get; set;}
public PointF One
{
get
{
return PointF.Add(_one, Skew);
}
set {_one = value; }
}
public PointF Two
{
get
{
return PointF.Add(_two, Skew);
}
set {_two = value; }
}
}
public class SlotGroup : List<SlotData>
{
internal SizeF Skew
{
set
{
foreach(var slotData in this)
{
slotData.Skew = value;
}
}
}
}
public class ClientData : List<SlotGroup>
{
private SizeF _skew;
public SizeF Skew
{
get { return _skew; }
set
{
_skew = value;
foreach (var slotGroup in this)
{
slotGroup.Skew = value;
}
}
}
}
I could not think of anything more elegant that would work. Encapsulation dictates that contained classes cannot access the data of thier container and the code to override the the child accesors on the container classes would have been more cumbersome.

Categories