La mia domanda è relativa a Is there a reasonable approach to "default" type parameters in C# Generics?, ma utilizzando una classe generica interna tale approccio non funziona.Posso rendere un generico facoltativo, per impostazione predefinita per una determinata classe?
codice dato in questo modo:
using System;
public class FooEventArgs<T> : EventArgs
{
// ... T properties and a constructor
}
public class Foo<T>
{
public delegate void EventHandler<FooEventArgs>(object sender, FooEventArgs<T> e);
public event EventHandler<FooEventArgs<T>> Changed
}
E con esso viene utilizzato in questo modo:
public class User
{
public Foo<int> foo1;
public Foo<object> foo2;
public User()
{
foo1 = new Foo<int>();
foo2 = new Foo<object>();
foo1.Changed += foo1_Changed;
foo2.Changed += foo2_Changed;
}
protected void foo1_Changed(object sender, FooEventArgs<int> e) { ... }
protected void foo2_Changed(object sender, FooEventArgs<object> e) { ... }
}
Beh, mi piacerebbe un po 'come se avessi potuto opzionale generica, in quanto non vi sarà ci sono molti casi in cui non so di che tipo entrerà qualcosa (i dati provengono da un sistema esterno che ha i propri tipi di variabili, che vengono poi convertiti in tipi .NET, ma mi imbatto in situazioni in cui, per esempio , un tipo di dati remoto può trasformarsi in uno di un paio di tipi .NET, o in cui è del "qualsiasi" tipo-così object
sarebbe l'unica vera risposta per quel caso)
La soluzione che subito mi venne in mente fu la creazione di sottoclassi (era anche il suggerimento primario nella questione legata alla prima):.
public class Foo : Foo<object>
{
public Foo(...) : base(...) { }
}
public class FooEventArgs : FooEventArgs<object>
{
public Foo(...) : base(...) { }
}
allora voglio usare in questo modo:
public class User
{
public Foo foo3;
public User()
{
foo3 = new Foo();
foo3.Changed += foo3_Changed;
}
protected void foo3_Changed(object sender, FooEventArgs e) { ... }
}
Il problema è che, naturalmente, non funziona con foo3_Changed
accettare FooEventArgs
; ha bisogno di FooEventArgs<object>
, poiché questo è ciò che l'evento Foo.Changed
otterrà ad esso (poiché il valore arriverà da Foo<object>
).
Foo.cs(3,1415926): error CS0123: No overload for 'foo3_Changed' matches delegate 'FooLibrary.Foo<object>.EventHandler<FooLibrary.FooEventArgs<object>>'
C'è qualcosa che posso fare su questo, a corto di duplicare gran parte della classe?
Ho provato un'altra cosa: un operatore implicito per convertire da FooEventArgs<object>
a FooEventArgs
.
public static implicit operator FooEventArgs(FooEventArgs<object> e)
{
return new FooEventArgs(...);
}
Questo, purtroppo, non sembra funzionare, anche se non sono del tutto chiaro il motivo per cui:
EditBuffer.cs(13,37): error CS0553: 'FooLibrary.FooEventArgs.implicit operator FooLibrary.FooEventArgs(FooLibrary.FooEventArgs<object>)': user-defined conversions to or from a base class are not allowed
Dunque, ancora una volta, c'è qualcosa che posso fare su questo, o ho ragione nel ritenere che sia Tough Luck e dovrò semplicemente accontentarmi di usare FooEventArgs<object>
(e quindi penso che possa anche usare lo Foo<object>
)?
[correlate] (https://github.com/dotnet/csharplang/issues/253) – Shimmy