C# Instantiating der Klasse mit zwei generischen Parametern Frage - Typ t kann nicht verwendet werden
Posted: 11 Aug 2025, 06:42
Ich prote nur einen asynchronen Befehl (Muster) für eine ASP.NET -Anwendung, die auf .NET 4.8 ausgeführt wird. T .
update
Wenn ich die Empfängerlinie ändere, um die tatsächlichen Arten von t und y zu haben und die Schnittstelle zu entfernen, die die Schnittstelle aus der Empfängerklasse erhalten kann. Schnittstelle.
Lösung
Wie üblich, halbe Stunde nach der Frage der Frage, dass ich die Lösung gefunden habe - ich werde sie hier veröffentlichen, wenn es hilfreich sein könnte. an: < /p>
Wenn ich T und y als ursprüngliche Absicht an die Empfängerklasse übergeben wollte. Ich musste die Schnittstellendefinition nach unten übereinstimmen: < /p>
Der Hauptteil bestand darin, die Definition hinzuzufügen, wobei y: class angezeigt wird, um anzuzeigen, dass String (oder komplexes Objekt) keinen Standardparameter hatte (wie t ).
Code: Select all
_receiver = (IStateReceiver)new StateReceiver();
< /code>
Mit dem Fehler lautet: < /p>
Der Typ 't' kann im generischen Typ oder in der Methode 'Stveseciver ' nicht als Typparameter 't' verwendet werden. Es gibt keine Konvertierung oder Typ-Parameterkonvertierung von Boxen von 't' zu 'state.istatereceiver '. unten mit einem Beispielverbrauch: < /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();
}
}
Wenn ich die Empfängerlinie ändere, um die tatsächlichen Arten von t und y zu haben und die Schnittstelle zu entfernen, die die Schnittstelle aus der Empfängerklasse erhalten kann. Schnittstelle.
Code: Select all
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>
Und hier ist der Empfänger ohne Schnittstelle (und eine grundlegende Zuordnung) < /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;
}
}
Wie üblich, halbe Stunde nach der Frage der Frage, dass ich die Lösung gefunden habe - ich werde sie hier veröffentlichen, wenn es hilfreich sein könnte. an: < /p>
Code: Select all
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;
}
}
Code: Select all
public interface IStateReceiver where T : new() where Y : class
{
Task RunCommand(Y command);
}
< /code>
Und dann kann die Initialize (Factory -Methode) auf folgende (Beispiel) erweitert werden < /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;
}