Het komt "ergens" vandaan, ja, dat neem ik aan / zijn we 't over eens. Of 't nou uit een UI komt of bepaald wordt a.d.h.v. de stand van de maan of whatever maakt niet uit.
3raser schreef op maandag 11 september 2017 @ 13:22:
Als je dat type weet dan is de naam voldoende om een nieuwe Instance aan te maken. Dan gaat
New Golf() niet werken omdat je dan de juiste class moet gaan bepalen aan de hand van If's. Met CreateInstance kun je dynamisch de juiste class oproepen.
Gegeven de volgende "basis":
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| interface ICar
{
void Drive();
void Stop();
}
public abstract class Car : ICar
{
public void Drive() { /* ... */ }
public void Stop() { /* ... */ }
}
public class Golf : Car { }
public class Clio : Car { }
public class Leon : Car { } |
Wat is het verschil volgens jou dan tussen volgende twee implementaties?
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| class CarFactory {
public ICar CreateCar(string name)
{
switch (name)
{
case "golf":
return new Golf();
case "clio":
return new Clio();
case "leon":
return new Leon();
default:
throw new NotSupportedException();
}
}
} |
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| class CarFactory {
public ICar CreateCar(string name)
{
switch (name)
{
case "golf":
return (ICar)Activator.CreateInstance(typeof(Golf));
case "clio":
return (ICar)Activator.CreateInstance(typeof(Clio));
case "leon":
return (ICar)Activator.CreateInstance(typeof(Leon));
default:
throw new NotSupportedException();
}
}
} |
Activator.CreateInstance heeft heus z'n nut wel, maar 't is, in deze discussie, niet meer dan een implementatiedetail betreffende
hoe je de instance maakt.
Als je doelt op iets als (uit de losse pols):
C#:
1
2
3
4
5
6
7
8
| class CarFactory {
public ICar CreateCar(string name)
{
var fqn = string.Format("{0}.{1}", typeof(ICar).Namespace, name);
return (ICar)Activator.CreateInstance(Type.GetType(fqn, true, true));
}
} |
Ja, dat scheelt een switch / boel if's, maar maakt je factory, zonder er extra werk/aandacht aan te besteden, wel vrij vatbaar voor misbruik. In essentie doe je hier een "eval()" en "eval == evil"

Daarbij, leert de/mijn ervaring, zal een Golf (zo niet nu danwel later) andere argumenten in de constructor verwachten dan een Leon of Clio en dan wordt het helemaal houwtje touwtje werk met Activator.CreateInstance. In het "new ...()" scenario heb je expliciet alle ondersteunde types uitgeschreven en kun je vrij eenvoudig de specifieke constructors die per ICar-implementatie (geheid gaan) verschillen met de juiste argumenten aanroepen.
Maar nogmaals; new() vs Activator.CreateInstance is een implementatie-detail en wat je daar kiest is een kwestie van persoonlijke voorkeur. Het
bovenliggende concept is een factory. En alle 3 de bovenstaande
CreateCar zijn dus een factory(method).
[
Voor 18% gewijzigd door
RobIII op 11-09-2017 16:02
]
There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.
Je eigen tweaker.me redirect
Over mij