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.
Related
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);
}
}
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.)
I have multiple classes like:
public class Base { }
public class Base1: Base { public static List<Base1> LoadFromXml(string path) }
public class Base2: Base { public static List<Base2> LoadFromXml(string path) }
Then I want to have a method like this:
public List<T> PrepareBase<T>() where T: Base { return T.Load("C:\test.xml"); }
So that I don't have to make a method for every type.
But I don't know how to accomplish this or something similar.
The problem is that I can't make the LoadFromXml method known to the base class because static inheritance is not a thing. Neither is creating a seperate interface with a static method.
Is there a way to do this or am I expecting too much?
Edit:
An example of the LoadFromXml method:
public class Base1
{
public int ID { get; set; }
public string PropertyOnlyInBase1 { get; set; }
public static List<Base1> LoadFromXml(string path)
{
List<Base1> baseList = new List<Base1>();
XDocument doc = XDocument.Load(path);
foreach(var node in doc.Descendants("Base1"))
{
Base 1 base = new Base1() { ID = node.Attributes["id"] };
base.PropertyOnlyInBase1 = node.Element("PropertyOnlyInBase1");
baseList.Add(base);
}
return baseList;
}
}
So the Base classes also have some unique properties. That's why I needed the inheritance thing in the first place.
One option is to add a GenericBase:
public abstract class Base
{
}
public static class GenericBase<T>
where T : Base
{
public static List<T> LoadFromXml(string path)
{
//Load from XML
}
}
public class Base1 : Base { }
public class Base2 : Base { }
public class Test //MainForm.cs class or whatever you want
{
public void Tester() //Load event handler or whatever you want
{
List<Base1> base1List = PrepareBase<Base1>();
}
public List<T> PrepareBase<T>() where T : Base
{ return GenericBase<T>.LoadFromXml("C:\test.xml"); }
}
Edit:
As D Stanley mentioned, it's not possible; but I made some work-around that could be helpful for you:
public abstract class Base
{
public static List<T> LoadFromXml<T>(string path) where T : Base, new()
{
List<T> baseList = new List<T>();
XDocument doc = XDocument.Load(path);
foreach (var node in doc.Descendants(typeof(T).Name))
{
T t = new T();
Dictionary<string, string> d = new Dictionary<string, string>();
foreach (var item in node.Elements())
d.Add(item.Name.ToString(), item.Value);
t.Load(d);
baseList.Add(t);
}
return baseList;
}
protected internal abstract void Load(Dictionary<string, string> elements);
}
public class Base1 : Base
{
public string CustomProp1 { get; set; }
public string CustomProp2 { get; set; }
public string CustomProp3 { get; set; }
protected internal override void Load(Dictionary<string, string> elements)
{
if (elements.ContainsKey("CustomProp1"))
CustomProp1 = elements["CustomProp1"];
if (elements.ContainsKey("CustomProp2"))
CustomProp2 = elements["CustomProp2"];
if (elements.ContainsKey("CustomProp3"))
CustomProp3 = elements["CustomProp3"];
}
}
public class Base2 : Base
{
public string CustomProp1 { get; set; }
public string CustomProp2 { get; set; }
public string CustomProp3 { get; set; }
protected internal override void Load(Dictionary<string, string> elements)
{
if (elements.ContainsKey("CustomProp1"))
CustomProp1 = elements["CustomProp1"];
if (elements.ContainsKey("CustomProp2"))
CustomProp2 = elements["CustomProp2"];
if (elements.ContainsKey("CustomProp3"))
CustomProp3 = elements["CustomProp3"];
}
}
public class Test //MainForm.cs class or whatever you want
{
public void Tester() //Load event handler or whatever you want
{
List<Base1> base1List = PrepareBase<Base1>();
}
public List<T> PrepareBase<T>() where T : Base, new()
{
return Base.LoadFromXml<T>("C:\test.xml");
}
}
I think you're correct that the class that loads these from XML should be separate from the class that's being loaded. As you said, it has no real connection to the instance.
Perhaps what you need is a separate class that loads those instances for you.
public class BaseXmlLoader<TBase> where TBase : Base
{
public List<TBase> LoadFromXml(string filePath)
{
var serializer = new XmlSerializer(typeof(TBase));
// Load your file and deserialize.
}
}
The benefits aren't huge because it's not saving you that much code. But if the LoadFromXml methods are essentially the same except for the type then you're getting something out of it.
I changed my approach to the problem and solved it using the Factory pattern. I also provided each class with an instance method SetPropertiesFromXml to handle the custom properties. Unlike the previously used method, a method like that made sense as an instance method.
Factory:
public static class BaseFactory
{
public static Base GetBase(string id)
{
switch(id) { case '1': return new Base1(); ... }
}
public static T GetBaseList<T>(string xml, string tagName) where T: Base
{
List<T> list = new List<T>();
var nodes = XDocument.Load(xml).Descendants(tagName);
foreach(XElement node in nodes)
{
var base = GetBase(node.Attribute("id").Value);
base.SetPropertiesFromXml(node);
list.Add(base as T);
}
}
}
Bases
public abstract class Base
{
public virtual void SetPropertiesFromXml(XElement node)
{
//<Set Properties like: this.Property = node.Element("key");>
}
}
public class Base1
{
public override void SetPropertiesFromXml(XElement node)
{
//<Set Custom Properties for Base1>
//Call Base to add the normal properties as well
base.SetPropertiesFromXml(node);
}
}
Call
List<Base1> list = BaseFactory.GetBaseList<Base1>("test.xml", "Base1");
I often end up writing classes like this:
public class Animal
{
public string Colour { get; set; }
public int Weight { get; set; }
public Animal(Dog data)
{
this.Colour = data.Colour;
this.Weight = data.Weight;
}
public Animal(Cat data)
{
this.Colour = data.Colour;
this.Weight = data.Weight;
}
}
When you have lots of properties and types then you quickly end up with a lot of boiler plate code. Ideally in this situation I would just create an IAnimal interface and reference that. I'm currently in a situation where the Dog and Cat classes exist in a third party assembly and I can't modify them. The only solution that I can come up with is:
public class Animal
{
public string Colour { get; set; }
public int Weight { get; set; }
public Animal(Cat data){Init(data);}
public Animal(Dog data){Init(data);}
private void Init(dynamic data)
{
this.Colour = data.Colour;
this.Weight = data.Weight;
}
}
This works but I lose all type safety, is there a better solution than constructor injection?
Thanks,
Joe
EDIT: Here is a real world example. I have a third party library which returns 3 objects called:
GetPageByIdResult
GetPagesByParentIdResult
GetPagesByDateResult
(These are all auto generated classes from a service reference and the properties are pretty much identical)
Instead of dealing with these three objects I want to deal with a single PageData object or a collection of them.
You can have the logic in one common constructor that all the other constructors call:
public class Animal
{
public string Colour { get; set; }
public int Weight { get; set; }
public Animal(Dog data) : this (data.Colour, data.Weight)
{
}
public Animal(Cat data) : this (data.Colour, data.Weight)
{
}
private Animal(string colour, int weight)
{
this.Colour = colour;
this.Weight = weight;
}
}
This is pretty similar to your second solution but it doesn't lose type safety.
I'm currently in a situation where the Dog and Cat classes exist in a
third party assembly and I can't modify them
I'd suggest Automapper-based solution:
public static class AnimalFactory
{
public static Animal Create<T>(T source)
where T : class
{
Mapper.CreateMap<T, Animal>();
return Mapper.Map<Animal>(source);
}
}
Usage:
var catAnimal = AnimalFactory.Create(cat);
var dogAnimal = AnimalFactory.Create(dog);
Of course, you can provide a way to custom mapping configuration, if needed.
If you do not want to have the class littered like that you can try Extension methods?
public static Animal ToAnimal(this Dog item)
{
return new Animal() {Weight = item.Weight, Colour = item.Colour};
}
public static Animal ToAnimal(this Cat item)
{
return new Animal() {Weight = item.Weight, Colour = item.Colour};
}
try using json serializer's, with that we can ensure type safety.
public class Animal
{
public string Colour { get; set; }
public long Weight { get; set; }
public string Name { get; set; }
public Animal Create<T>(T anyType)
{
return GetObject<T, Animal>(anyType);
}
public K GetObject<T, K>(T type1)
{
try
{
var serialized = JsonConvert.SerializeObject(type1);
return JsonConvert.DeserializeObject<K>(serialized);
}
catch (Exception ex)
{
return default(K);
}
}
}
class Program
{
public static void Main(string[] args)
{
Animal obj = new Animal();
var animal = obj.Create(new { Colour = "Red", Weight = 100 });
//here you can pass any object, only same name properties will be initialized..
Console.WriteLine(animal.Colour + " : " + animal.Weight);
Console.ReadKey();
}
}
I have two classes (this is C#) that are very similar except they each contain their own nested class and enum.
I would like to refactor them to both inherit from a single abstract class, but I'm running into a problem because the methods are all tightly coupled to the nested class types.
My first plan was to pull out the ItemDetails Class, but it is linked to the ItemType, which is an enum that is specific to each view item class. Further, I can't just use System.Enum as the type since I need to be able to serialize the details to an xml file.
How could I reduce the duplication within these classes?
public class FirstViewItem
{
[Serializable]
public class ItemDetails
{
public ItemType Type;
public int Width;
public string Text;
public int DisplayOrder;
}
public enum ItemType
{
None = 0,
A,
B,
C
}
public FirstViewItem()
{
// ...
}
public List<ItemDetails>()
{
// code here ...
}
}
public class SecondViewItem
{
[Serializable]
public class ItemDetails
{
public ItemType Type;
public int Width;
public string Text;
public int DisplayOrder;
}
public enum ItemType
{
None = 0,
X,
Y,
X
}
public SecondViewItem()
{
// ...
}
public List<ItemDetails>()
{
// code here ...
}
}
You want to make a generic class that is dependent on the item type enum being passed in:
public class ViewItem<T>
{
[Serializable]
public class ItemDetails
{
public T Type; // the generic type is inserted here
public int Width;
public string Text;
public int DisplayOrder;
}
// common code that uses ItemDetails
}
Then some item types:
public enum FirstItemType
{
None = 0,
A,
B,
C
}
public enum SecondItemType
{
None = 0,
X,
Y,
Z
}
Then usage:
var firstViewItem = new ViewItem<FirstItemType>();
Yamen's answer is good.
I'd started writing this so i'll finish. Here's an example of using generics with a base class and some inheriting classes:
public class BaseClass<T>
{
public T NestedClass{get;set;}
}
public class MainOne : BaseClass<MainOneType>
{
}
public class MainTwo : BaseClass<MainTwoType>
{
}
public class MainOneType
{
}
public class MainTwoType
{
}
I ended up using ideas from 2 different answers, so I'll answer with the combined result.
public class BaseViewItem<T> where T : struct
{
[Serializable]
public class ItemDetails
{
public T Type;
public int Width;
public string Text;
public int DisplayOrder;
}
public FirstViewItem()
{
// ...
}
public List<ItemDetails>()
{
// code here ...
}
}
public class FirstViewItem : BaseViewItem<FirstItemType>
{
// class-specific code...
}
public class SecondViewItem : BaseViewItem<SecondItemType>
{
// class-specific code...
}
public enum FirstItemType
{
None = 0, A, B, C
}
public enum SecondItemType
{
None = 0, X, Y, Z
}