How can I make 1 class (base, generic or something else) from these two classes?
class A
{
A Link { get; set; }
}
class B
{
B Link { get; set; }
}
UPD: This is what I have now:
class BSTree
{
public BSTNode Root { get; set; }
}
class AVLTree
{
public AVLNode Root { get; set; }
}
class BSTNode
{
public BSTNode Parent { get; set; }
public BSTNode Left { get; set; }
public BSTNode Right{ get; set; }
public int Key{ get; set; }
}
class AVLNode
{
public AVLNode Parent { get; set; }
public AVLNode Left { get; set; }
public AVLNode Right{ get; set; }
public int Key{ get; set; }
public int Height { get; set;}
}
And finally I want to get something like BaseNode and BaseTree.
What is Link
? If you have a base class Base
with A : Base
and B : Base
, do you need to know that a.Link
is of type A
and b.Link
is of type B
?
If not, it is as easy as:
public abstract class Base
{
public Base Link { get; set; }
}
If, on the other hand, you need to preserve the type of Link
, then what about generics?
public class Common<T>
{
public T Link { get; set; }
}
which can be used like this:
public static void Main()
{
var number = new Common<int>
{
Link = 27,
};
var text = new Common<string>
{
Link = "Hello World",
};
// This is impossible, because of the mismatch between types.
////var wrong = new Common<float>
////{
//// Link = "I'm not a float.",
////};
Console.WriteLine(number.Link);
Console.WriteLine(text.Link);
}
1. Refactoring: local method
Specifying both the generic type and the link is annoying, especially if you have to change the types a lot. In some cases, you may even mistakenly specify the wrong type: either a parent class or a class which supports implicit type conversion, resulting in difficult to find bugs.
To avoid this, you can create a method which initializes a new instance of the Common<T>
class based on the link:
public static void Main()
{
var number = CreateCommon(27);
var text = CreateCommon("Hello World");
Console.WriteLine(number.Link);
Console.WriteLine(text.Link);
}
private static Common<T> CreateCommon<T>(T link)
{
return new Common<T>
{
Link = link,
};
}
public class Common<T>
{
public T Link { get; set; }
}
2. Refactoring: factory pattern
The first refactoring is enough if you use the Common
class in one method. If you’re using it in several classes, then you’ll end up duplicating code (i.e. copy-pasting the CreateCommon
method), or refactoring the previous piece of code into a one which uses a factory:
public static void Main()
{
var number = Common.Factory.Create(27);
var text = Common.Factory.Create("Hello World");
Console.WriteLine(number.Link);
Console.WriteLine(text.Link);
}
public class Common<T> : Common
{
public Common()
{
// Do something here.
}
public Common(T link)
: this()
{
this.Link = link;
}
public T Link { get; set; }
}
public class Common
{
public static CommonFactory Factory
{
get
{
return new CommonFactory();
}
}
}
public class CommonFactory
{
public Common<T> Create<T>(T link)
{
return new Common<T>(link);
}
}
2
public abstract class Wrapper {
private A theA;
private B theB;
// these are private on purpose.
// add properties and methods for A and B stuff that you
// want to expose. Make sure the names look like they're
// all from one coherent class.
// make them `protected` as needed for use by only the subclasses.
// do not give a default constructor so you force subclasses
// to build correctly
public Wrapper (A a, B b) {
// check for null!
theA = a;
theB = b;
}
}