Reputation: 431
I have the class structure like below:
public interface IBinder<T>
where T : Control
{
T Control { get; }
}
public class ButtonBinder : IBinder<Button>
{
public ButtonBinder(Button control)
{
Control = control ?? throw new ArgumentNullException(nameof(control));
}
public Button Control { get; private set; }
}
Create instances of that Binder I want with help of a factory method like this:
public void Main()
{
// This line works.
var binder = RegisterBinder<ButtonBinder, Button>(new Button());
// But I want use type inference like this:
var binder2 = RegisterBinder<ButtonBinder>(new Button());
}
/// <summary>
/// My pseudo-factory.
/// </summary>
public T_Binder RegisterBinder<T_Binder, T_Control>(T_Control control)
where T_Binder : IBinder<T_Control>
where T_Control : Control
{
return (T_Binder)Activator.CreateInstance(typeof(T_Binder), control);
}
Because the class 'ButtonBinder' declares the generic control type 'Button' the Compiler should be able to infer it. How I can tell the compiler that I want to use type inference?
Thank you.
Upvotes: 0
Views: 70
Reputation: 1555
Unfortunately C# cannot infer only one of multiple generic parameters. However, if you do not mind capturing the inferable type in an intermediate class you can do something like this:
public class Factory
{
public void Main()
{
// This line works.
var binder = RegisterBinder<ButtonBinder, Button>(new Button());
// Now only T_Binder is needed
var binder2 = ForControl(new Button()).RegisterBinder<ButtonBinder>();
}
private BinderRegistration<T_Control> ForControl<T_Control>(T_Control control) where T_Control : Control
{
return new BinderRegistration<T_Control>(control);
}
/// <summary>
/// My pseudo-factory.
/// </summary>
public T_Binder RegisterBinder<T_Binder, T_Control>(T_Control control)
where T_Binder : IBinder<T_Control>
where T_Control : Control
{
return (T_Binder)Activator.CreateInstance(typeof(T_Binder), control);
}
}
internal class BinderRegistration<T_Control>
where T_Control : Control
{
private readonly Control _control;
public BinderRegistration(Control control)
{
_control = control;
}
public T_Binder RegisterBinder<T_Binder>()
where T_Binder : IBinder<T_Control>
{
return (T_Binder)Activator.CreateInstance(typeof(T_Binder), _control);
}
}
Upvotes: 1