Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8938323
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 15, 20262026-06-15T10:35:54+00:00 2026-06-15T10:35:54+00:00

My question is related to Is there a reasonable approach to "default" type parameters

  • 0

My question is related to Is there a reasonable approach to "default" type parameters in C# Generics?, but using an inner generic class that approach doesn’t work.

Given code like this:

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
}

And with it being used like this:

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) { ... }
}

Well, I’d rather like it if I could have the generic optional, as there will be many cases where I don’t know what type something will be coming in. (Data is coming from an external system which has its own variable types, which are then converted into .NET types, but I run into situations where, for example, one remote data type may turn into one of a couple of .NET types, or where it is of the “any” type—thus object would be the only real answer for that case.)

The solution which immediately occurred to me was subclassing (it was also the primary suggestion in the question linked to earlier):

public class Foo : Foo<object>
{
    public Foo(...) : base(...) { }
}

public class FooEventArgs : FooEventArgs<object>
{
    public Foo(...) : base(...) { }
}

I then want to use it like this:

public class User
{
    public Foo foo3;

    public User()
    {
        foo3 = new Foo();
        foo3.Changed += foo3_Changed;
    }

    protected void foo3_Changed(object sender, FooEventArgs e) { ... }
}

The problem is that it naturally won’t work with foo3_Changed accepting FooEventArgs; it needs FooEventArgs<object>, as that’s what the Foo.Changed event will get pass to it (as the value will come from Foo<object>).

Foo.cs(3,1415926): error CS0123: No overload for 'foo3_Changed' matches delegate 'FooLibrary.Foo<object>.EventHandler<FooLibrary.FooEventArgs<object>>'

Is there anything I can do about this, short of duplicating much of the class?

I did try one other thing: an implicit operator to convert from FooEventArgs<object> to FooEventArgs.

    public static implicit operator FooEventArgs(FooEventArgs<object> e)
    {
        return new FooEventArgs(...);
    }

This, unfortunately, doesn’t seem to work, though I’m not quite clear on why:

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

So then, once again, is there anything I can do about this, or am I correct in thinking that it’s Tough Luck and I’ll just have to be content using FooEventArgs<object> (and then I guess I may as well just use Foo<object>)?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-15T10:35:55+00:00Added an answer on June 15, 2026 at 10:35 am

    I don’t think there’s much you can do about it, to be honest. You could make Foo doubly generic:

    public class Foo<TData, TArgs> where TArgs : FooEventArgs<TData>
    {
        public delegate void EventHandler<TArgs>(object sender, TArgs e);
        public event EventHandler<TArgs> Changed;
    }
    

    Then you could write:

    public class Foo : Foo<object, FooEventArgs>
    

    … but it’s really making things very complicated for very little benefit.

    I would also say that even though it’s a bit more verbose to include the type argument, it does make it very clear – whereas inheritance can muddy the waters in various ways. I’d steer clear of class inheritance when you’re not really trying to model behaviour specialization.

    The reason your implicit conversion doesn’t work has nothing to do with generics, by the way – as the error message states, you can’t declare a conversion (implicit or explicit) which goes up or down the inheritance hierarchy. From the C# spec section 6.4.1:

    C# permits only certain user-defined conversions to be declared. In particular, it is not possible to redefine an already existing implicit or explicit conversion.

    (See that section for more details.)


    As a side note, I find it more common to use inheritance the other way round for generics, typically with interfaces:

    public interface IFoo
    {
        // Members which don't depend on the type parameter
    }
    
    public interface IFoo<T> : IFoo
    {
        // Members which all use T
    }
    

    That way code can receive just an IFoo without worrying about the generics side of things if they don’t need to know T.

    Unfortunately, that doesn’t help you in your specific case.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I've been using the search function but I think there isn't any related question
There is another possibly related question on this but it didn't have answers and
this question is related to c++ there is a library which declares a class
There is a related question to this: What's the best method to pass parameters
This question is related with one of my earlier questions.. Previous Post In there
This question is related to a previous post . Is there something comparable to
Related to an earlier question I asked, I've seen that there's both LoadComponent() and
This is related to another open question of mine . While there aren't any
I want to expand on the functionality related to this question . Is there
Is there a list of COM error codes somewhere? Related: HRESULT: 0x80010105 (RPC_E_SERVERFAULT) question

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.