Паттерн принимает команду типа y , использует его, чтобы вывести приемник (метод заводя t .
По большей части это работает, за исключением того, что я не могу понять, как создать экземпляр приемника из -за t , имеющего ограничение, где t: new ()
Строка, вызывающая проблему, является:
.
Код: Выделить всё
_receiver = (IStateReceiver)new StateReceiver();
< /code>
С ошибкой: < /p>
Тип 't' не может использоваться в качестве параметра типа 't' в общем типе или методе 'staterceiver '. Не существует преобразования в боксе или преобразования параметров типа от 't' в atember.istaterceiver '. < /P>
' t 'должен быть неабстроктным типом с общедоступным конструктором без параметра ' < /p>
'< /p>
' < /p>
'< /p>
public interface IStateCommand
{
Task ExecuteAsync();
}
public interface IStateReceiver
{
Task RunCommand(Y command);
}
public sealed class StateCommand : IStateCommand
{
private IStateReceiver _receiver;
private Y _command;
private StateCommand() { /* no body */ }
public static Task CreateAsync(Y command)
{
var ret = new StateCommand();
return ret.Initialize(command);
}
public async Task Initialize(Y command)
{
_command = command;
_receiver = (IStateReceiver)new StateReceiver();
await Task.Delay(1000);
return this;
}
public async Task ExecuteAsync()
{
return await this._receiver.RunCommand(this._command);
}
}
// Example receiver.
public class StateReceiver where T: IStateReceiver, new()
{
public async Task RunCommand(Y command)
{
// Perform action here.
await Task.Delay(1000);
// Can be simple type e.g. int or complex eg BobsResultObject. Just returning default here for now.
return new T();
}
}
// Example invoke
public class StateInvoker
{
public async void PerformCommand()
{
String command = "BobsCommand";
StateCommand bobsCommandObject = await StateCommand.CreateAsync(command);
var bobsResult = bobsCommandObject.ExecuteAsync();
}
}
, если я изменяю строку приемника, чтобы иметь фактические типы t и y и удалить интерфейс из класса приемника, я могу получить его для компиляции. the interface.
Here is the two parts of code (with the factory implementation)
Код: Выделить всё
private async Task Initialize(Y command)
{
_command = command;
if (typeof(Y) == typeof(string))
{
String localCommand = command as String;
if (localCommand != null)
{
switch (localCommand.ToLower())
{
case "bobscommand":
_receiver = new StateReceiver() as IStateReceiver;
break;
}
}
}
return this;
}
< /code>
И вот приемник без интерфейса (и некоторое основное назначение) < /p>
public class StateReceiver where T : new()
{
public async Task RunCommand(Y command)
{
// Perform action here.
await Task.Delay(1000);
T t = new T();
if (typeof(T) == typeof(int))
t = (T)(object)42;
else
t = (T)(object)null;
return t;
}
}
, как обычно, через полчаса после задания вопроса, который я нашел решение - поэтому я опубликую его здесь, если это может быть полезно. к: < /p>
Код: Выделить всё
public class StateReceiver : IStateReceiver where T : new() where Y : class
{
public async Task RunCommand(Y command)
{
// Perform action here.
await Task.Delay(1000);
T t = new T();
if (typeof(T) == typeof(int))
t = (T)(object)42;
else
t = (T)(object)null;
return t;
}
}
Код: Выделить всё
public interface IStateReceiver where T : new() where Y : class
{
Task RunCommand(Y command);
}
< /code>
, а затем инициализация (метод заводского) может быть расширена на следующее (пример) < /p>
private async Task
> Initialize(Y command)
{
_command = command;
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
await Task.Run(() =>
{
if (typeof(Y) == typeof(string))
{
String localCommand = command as String;
if (localCommand != null)
{
switch (localCommand.ToLower())
{
case "bobscommand":
_receiver = new StateReceiver() as IStateReceiver;
break;
}
}
}
}, token);
return this;
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... e-t-cannot
Мобильная версия