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>)?

questionAnswers(2)

yourAnswerToTheQuestion