Czy mogę sprawić, aby rodzajowy był opcjonalny, domyślnie dla pewnej klasy?
Moje pytanie jest związane zCzy istnieje rozsądne podejście do parametrów typu „domyślnego” w C # Generics?, ale użycie wewnętrznej klasy rodzajowej nie działa.
Podany kod w ten sposób:
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
}
Używając tego w ten sposób:
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) { ... }
}
Cóż, wolałbym, jeśli mógłbym mieć opcjonalny rodzajowy, ponieważ będzie wiele przypadków, w których nie wiem, jakiego typu coś się pojawi. (Dane pochodzą z zewnętrznego systemu, który ma własne typy zmiennych , które są następnie konwertowane na typy .NET, ale natrafiam na sytuacje, w których na przykład jeden zdalny typ danych może przekształcić się w jeden z kilku typów .NET lub gdzie jest typu „dowolnego” - w ten sposóbobject
byłaby jedyną prawdziwą odpowiedzią na tę sprawę.)
Rozwiązaniem, które natychmiast przyszło mi do głowy, było podklasowanie (była to również główna sugestia w pytaniu powiązanym z wcześniejszym):
public class Foo : Foo<object>
{
public Foo(...) : base(...) { }
}
public class FooEventArgs : FooEventArgs<object>
{
public Foo(...) : base(...) { }
}
Chcę to wykorzystać w ten sposób:
public class User
{
public Foo foo3;
public User()
{
foo3 = new Foo();
foo3.Changed += foo3_Changed;
}
protected void foo3_Changed(object sender, FooEventArgs e) { ... }
}
Problem polega na tym, że naturalnie nie zadziałafoo3_Changed
akceptującFooEventArgs
; to potrzebujeFooEventArgs<object>
, jak to jestFoo.Changed
zdarzenie zostanie mu przekazane (ponieważ wartość będzie pochodzić zFoo<object>
).
Foo.cs(3,1415926): error CS0123: No overload for 'foo3_Changed' matches delegate 'FooLibrary.Foo<object>.EventHandler<FooLibrary.FooEventArgs<object>>'
Czy mogę coś z tym zrobić, nie mówiąc o powielaniu dużej części klasy?
Spróbowałem jeszcze jednej rzeczy: niejawnego operatora do konwersjiFooEventArgs<object>
doFooEventArgs
.
public static implicit operator FooEventArgs(FooEventArgs<object> e)
{
return new FooEventArgs(...);
}
To niestety nie działa, chociaż nie wiem dokładnie, dlaczego:
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
Czy więc jest jeszcze coś, co mogę zrobić w tej sprawie, czy też mam rację, myśląc, że jest to Tough Luck, a ja po prostu muszę się zadowolićFooEventArgs<object>
(i wtedy chyba równie dobrze mogę użyćFoo<object>
)?