Let's assume, that we have the following classes:
class ViewModelA
{
private ProxyA proxy;
public ViewModelA(DataA data)
{
proxy = new ProxyA(data);
}
public void DoSth()
{
proxy.DoSth();
}
public ProxyA Proxy
{
get
{
return proxy;
}
}
}
class ViewModelB
{
private ProxyB proxy;
public ViewModelB(DataB data)
{
proxy = new ProxyB(data);
}
public void DoSth()
{
proxy.DoSth();
}
public ProxyB Proxy
{
get
{
return proxy;
}
}
}
...
All of these classes are actually a lot longer, but also similar in the same degree.
Is there a (nice) way of converting them all to one generic class? The core problem is the line:
proxy = new ProxyA(data);
because C# disallows calling parametrized ctors on generic class specializations (in terms of T
).
You can solve this by passing in a preconstructed ProxyA
or ProxyB
object.
One way of doing it is through inheritance, constructing the object just before calling the base constructor:
class ViewModel<TProxy, TData>
{
private TProxy proxy;
public ViewModel(TProxy proxy)
{
this.proxy = proxy;
}
public void DoSth()
{
proxy.DoSth();
}
public TProxy Proxy
{
get
{
return proxy;
}
}
}
class ViewModelA : ViewModel<ProxyA, DataA>
{
public ViewModelA(DataA data) : base(new ProxyA(data))
{
}
}
I've assumed here that DataA
and DataB
occurs somewhere in method signatures that you have omitted. If not, you can leave out the TData
generic type parameter.
Reflection is always an option, but it is best avoided if a solution like this is acceptable. If you want to avoid having to create a new type for a different TProxy
and TData
, you could add a second constructor instead:
ViewModel(TData data, Func<TData, TProxy> factory) : this(factory(data))
{
}
Used as such:
new ViewModel<ProxyA, DataA>(new DataA(), data => new ProxyA(data));
I'm not sure if that makes sense to do in your application however.
If you know the type (and using generics you would), you can call Activator.CreateInstance to create an instance of that type using any constructor you want.
proxy = Activator.CreateInstance(typeof(TProxy), new[]{data});
While this will solve your direct problem, you could also think about a design where ViewModelA
does not know about DataA
and instead gets passed a ProxyA
. That would solve all your problems without fancy reflection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With