C# Компания Comentiating Class с двумя общими параметрами Вопрос - тип t нельзя использоватьC#

Место общения программистов C#
Ответить
Anonymous
 C# Компания Comentiating Class с двумя общими параметрами Вопрос - тип t нельзя использовать

Сообщение Anonymous »

Я только что прототипирую асинхронную обработчик команды (шаблона) для приложения ASP.NET, работающего на .net 4.8.
Паттерн принимает команду типа 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();
}
}
update
, если я изменяю строку приемника, чтобы иметь фактические типы 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;
}
}
solution
, как обычно, через полчаса после задания вопроса, который я нашел решение - поэтому я опубликую его здесь, если это может быть полезно. к: < /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;
}
}
If I wanted to pass T and Y through to the receiver class as the original intent. Мне нужно было изменить определение интерфейса, чтобы соответствовать ниже: < /p>

Код: Выделить всё

 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;
}
Основной частью было добавление h y: class в определение, чтобы указать, что строка (или сложный объект) не имел параметра по умолчанию (как t ).


Подробнее здесь: https://stackoverflow.com/questions/797 ... e-t-cannot
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»