Reputation: 811
This is a thought exercise. I don't need help simplifying this code or to accomplish the same thing without relating the types. The code is convoluted because it attempts to identify a pattern that could be used if alternatives were not available.
The idea is to see if one can create arbitrary relationships between various types that is enforced by the compiler.
I want to be able create a set of types {T1, T2, T3, T4, ...}
that are related to another set of types {Ta, Tb, Tc, Td, ... }
in the same way. Once the relationship is established, I want to be able to use a type in the second set, by only using the related type in the first set. For example, if a function is given type T5, it should be able to create an instance of Te because T5 and Te are related.
In the example below, I'm using the types {Nail, Screw}
and I want to relate them to their makers {NailMaker, ScrewMaker}
. One constraint of this thought exercise is to use the type Nail to create a NailMaker, and not an instance of Nail to do so.
The objective is to be able to call a static member of a base class Maker
with a type in the first set, to make an instance of the related type in the second set:
var factory = Maker<Nail>.Get()
Here factory
would be an instance of NailMaker
derived from Maker<Nail>
, and Get()
is a static function.
I need to somehow relate NailMaker
to Nail
but I haven't found a way to do that.
Something like:
static public Maker<T> Get()
{
return T.GetMaker();
}
I have tried this and it works:
public abstract class Maker<T>
{
static public Maker<T> Get<T2>() where T2: Maker<T>, new()
{
return new T2();
}
}
However, I'd like it to work without passing T2.
Upvotes: 1
Views: 158
Reputation: 4440
Editing the whole answer as this is much cleaner and closer to what you need.
First the Maker
class (your T2
). You would add the generic properties and methods your need :
public class Maker
{
public string Name { get; set; } = "";
}
Then the Part
parent class that describe the parts and contain the matching Maker
class
public class Part<T> where T : Maker
{
public static Type MakerType { get { return typeof(T); } }
}
Then you need 1 Maker
to match each Part
so you create those :
public class NailMaker : Maker { public NailMaker() { Name = "Nail"; } }
public class ScrewMaker : Maker { public ScrewMaker() { Name = "Screw"; } }
Then we need the Part
for each and with the T2
/ Maker
class they are referring too.
public class Nail : Part<NailMaker> { }
public class Screw : Part<ScrewMaker> { }
Then getting the Maker
class only required instantiation of the Type
lying in the Part
class that is Static
hence no need to instantiate the Part
class
var nailMaker = Activator.CreateInstance(Nail.MakerType);
var screwMaker = Activator.CreateInstance(Screw.MakerType);
Upvotes: 2
Reputation: 794
I'm not sure where you will apply the usage of it, but refering to Factory pattern you can implement something like this:
abstract class Maker {
public abstract int SomeProperty { get; }
}
abstract class MakerFactory {
public abstract Maker GetMaker();
}
class Nail:Maker {
}
class ConcreteNailFactory:NailFactory {
public override Maker GetMaker() {
return new Nail();
}
}
Upvotes: 0