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

  • SEARCH
  • Home
  • 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 6472005
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 25, 20262026-05-25T06:17:27+00:00 2026-05-25T06:17:27+00:00

What would be a practical advantage of using generics vs interfaces in this case:

  • 0

What would be a practical advantage of using generics vs interfaces in this case:

void MyMethod(IFoo f) 
{
}

void MyMethod<T>(T f) : where T : IFoo
{
}

I.e. what can you do in MyMethod<T> that you couldn’t in the non-generic version? I’m looking for a practical example, I know what the theoretical differences are.

I know that in MyMethod<T>, T will be the concrete type, but nonetheless I will only be able to use it as an IFoo within the body of the method. So what would be a real advantage?

  • 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-05-25T06:17:28+00:00Added an answer on May 25, 2026 at 6:17 am

    Well, one advantage as mentioned elsewhere, would be the ability to return a specific type of IFoo type if you return a value. But since your question is specifically about void MyMethod(IFoo f), I wanted to give a realistic example of at least one type of situation where using a generic method makes more sense (to me) than the interface. (Yes I spent a bit of time on this, but I wanted to try out some different ideas. :D)

    There are two blocks of code, the first is just the generic method itself and some context, the second is the full code for the example, including lots of comments ranging from notes on possible differences between this and an equivalent non-generic implementation, as well as various things I tried while implementing that didn’t work, and notes on various choices I made, etc. TL;DR and all that.

    Concept

        public class FooChains : Dictionary<IFoo, IEnumerable<IFoo>> { }
    
        // to manage our foos and their chains. very important foo chains.
        public class FooManager
        {
            private FooChains myChainList = new FooChains();
    
            // void MyMethod<T>(T f) where T : IFoo
            void CopyAndChainFoo<TFoo>(TFoo fromFoo) where TFoo : IFoo
            {
                TFoo toFoo;
    
                try {
                    // create a foo from the same type of foo
                    toFoo = (TFoo)fromFoo.MakeTyped<TFoo>(EFooOpts.ForChain);
                }
                catch (Exception Ex) {
                    // hey! that wasn't the same type of foo!
                    throw new FooChainTypeMismatch(typeof(TFoo), fromFoo, Ex);
                }
    
                // a list of a specific type of foos chained to fromFoo
                List<TFoo> typedFoos;
    
                if (!myChainList.Keys.Contains(fromFoo))
                {
                    // no foos there! make a list and connect them to fromFoo
                    typedChain = new List<TFoo>();
                    myChainList.Add(fromFoo, (IEnumerable<IFoo>)typedChain);
                }
                else
                    // oh good, the chain exists, phew!
                    typedChain = (List<TFoo>)myChainList[fromFoo];
    
                // add the new foo to the connected chain of foos
                typedChain.Add(toFoo);
    
                // and we're done!
            }
        }
    

    Gory Details

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace IFooedYouOnce
    {
        // IFoo
        //
        // It's personality is so magnetic, it's erased hard drives.
        // It can debug other code... by actually debugging other code.
        // It can speak Haskell... in C. 
        //
        // It *is* the most interesting interface in the world.
        public interface IFoo
        {       
            // didn't end up using this but it's still there because some
            // of the supporting derived classes look silly without it.
            bool CanChain { get; }
            string FooIdentifier { get; }
    
            // would like to place constraints on this in derived methods
            // to ensure type safety, but had to use exceptions instead.
            // Liskov yada yada yada...
            IFoo MakeTyped<TFoo>(EFooOpts fooOpts);
        }
    
        // using IEnumerable<IFoo> here to take advantage of covariance;
        // we can have lists of derived foos and just cast back and 
        // forth for adding or if we need to use the derived interfaces.
    
        // made it into a separate class because probably there will be
        // specific operations you can do on the chain collection as a
        // whole so this way there's a spot for it instead of, say, 
        // implementing it all in the FooManager
        public class FooChains : Dictionary<IFoo, IEnumerable<IFoo>> { }
    
        // manages the foos. very highly important foos.
        public class FooManager
        {
            private FooChains myChainList = new FooChains();
    
            // would perhaps add a new() constraint here to make the 
            // creation a little easier; could drop the whole MakeTyped
            // method.  but was trying to stick with the interface from
            // the question.
            void CopyAndChainFoo<TFoo>(TFoo fromFoo) where TFoo : IFoo
            // void MyMethod<T>(T f) where T : IFoo
            {
                TFoo toFoo;
    
                // without generics, I would probably create a factory
                // method on one of the base classes that could return
                // any type, and pass in a type. other ways are possible,
                // for instance, having a method which took two IFoos, 
                // fromFoo and toFoo, and handling the Copy elsewhere.
    
                // could have bypassed this try/catch altogether because
                // MakeTyped functions throw if the types are not equal,
                // but wanted to make it explicit here. also, this gives
                // a more descriptive error which, in general, I prefer
                try
                {
                    // MakeTyped<TFoo> was a solution to allowing each TFoo
                    // to be in charge of creating its own objects
                    toFoo = 
                        (TFoo)fromFoo.MakeTyped<TFoo>(EFooOpts.ForChain);
                }
                catch (Exception Ex) {
                    // tried to eliminate the need for this try/catch, but
                    // didn't manage. can't constrain the derived classes'
                    // MakeTyped functions on their own types, and didn't
                    // want to change the constraints to new() as mentioned
                    throw 
                        new FooChainTypeMismatch(typeof(TFoo), fromFoo, Ex);
                }
    
                // a list of specific type foos to hold the chain
                List<TFoo> typedFoos;
    
                if (!myChainList.Keys.Contains(fromFoo))
                {
                    // we just create a new one and link it to the fromFoo
                    // if none already exists
                    typedFoos = new List<TFoo>();
                    myChainList.Add(fromFoo, (IEnumerable<IFoo>)typedFoos);
                }
                else
                    // otherwise get the existing one; we are using the 
                    // IEnumerable to hold actual List<TFoos> so we can just
                    // cast here.
                    typedFoos = (List<TFoo>)myChainList[fromFoo];
    
                // add it in!
                typedFoos.Add(toFoo);
            }
        }
    
        [Flags]
        public enum EFooOpts
        {
            ForChain   = 0x01,
            FullDup    = 0x02,
            RawCopy    = 0x04,
            Specialize = 0x08
        }
    
        // base class, originally so we could have the chainable/
        // non chainable distinction but that turned out to be 
        // fairly pointless since I didn't use it. so, just left
        // it like it was anyway so I didn't have to rework all 
        // the classes again.
        public abstract class FooBase : IFoo
        {
            public string FooIdentifier { get; protected set; }
            public abstract bool CanChain { get; }
            public abstract IFoo MakeTyped<TFoo>(EFooOpts parOpts);
        }
    
        public abstract class NonChainableFoo : FooBase
        {
            public override bool CanChain { get { return false; } }
        }
    
        public abstract class ChainableFoo : FooBase
        {
            public override bool CanChain { get { return true; } }
        }
    
        // not much more interesting to see here; the MakeTyped would
        // have been nicer not to exist, but that would have required
        // a new() constraint on the chains function.  
        //
        // or would have added "where TFoo : MarkIFoo" type constraint
        // on the derived classes' implementation of it, but that's not 
        // allowed due to the fact that the constraints have to derive
        // from the base method, which had to exist on the abstract 
        // classes to implement IFoo.
        public class MarkIFoo : NonChainableFoo
        {
            public MarkIFoo()
                { FooIdentifier = "MI_-" + Guid.NewGuid().ToString(); }
    
            public override IFoo MakeTyped<TFoo>(EFooOpts fooOpts) 
            {
                if (typeof(TFoo) != typeof(MarkIFoo))
                    throw new FooCopyTypeMismatch(typeof(TFoo), this, null);
    
                return new MarkIFoo(this, fooOpts);
            }
    
            private MarkIFoo(MarkIFoo fromFoo, EFooOpts parOpts) :
                this() { /* copy MarkOne foo here */ }
        }
    
        public class MarkIIFoo : ChainableFoo
        {
            public MarkIIFoo()
                { FooIdentifier = "MII-" + Guid.NewGuid().ToString(); }
    
            public override IFoo MakeTyped<TFoo>(EFooOpts fooOpts)
            {
                if (typeof(TFoo) != typeof(MarkIIFoo))
                    throw new FooCopyTypeMismatch(typeof(TFoo), this, null);
    
                return new MarkIIFoo(this, fooOpts);
            }
    
            private MarkIIFoo(MarkIIFoo fromFoo, EFooOpts parOpts) :
                this() { /* copy MarkTwo foo here */ }
        }
    
        // yep, really, that's about all. 
        public class FooException : Exception
        {
            public Tuple<string, object>[] itemDetail { get; private set; }
    
            public FooException(
                string message, Exception inner,
                params Tuple<string, object>[] parItemDetail
            ) : base(message, inner)
            {
                itemDetail = parItemDetail;
            }
    
            public FooException(
                string msg, object srcItem, object destType, Exception inner
            ) : this(msg, inner,
                Tuple.Create("src", srcItem), Tuple.Create("dtype", destType)
            ) { }
        }
    
        public class FooCopyTypeMismatch : FooException
        {
            public FooCopyTypeMismatch(
                Type reqDestType, IFoo reqFromFoo, Exception inner
            ) : base("copy type mismatch", reqFromFoo, reqDestType, inner)
            { }
        }
    
        public class FooChainTypeMismatch : FooException
        {
            public FooChainTypeMismatch(
                Type reqDestType, IFoo reqFromFoo, Exception inner
            ) : base("chain type mismatch", reqFromFoo, reqDestType, inner)
            { }
        }
    }
    
    // I(Foo) shot J.R.!
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

What would be the best practice for sharing localization object (in this case ResourceBundle,
I would like to know a few practical use-cases (if they are not related/tied
I would like to know, in a practical sense, on a large scale (Java
I have used Flex for about a year before deciding that I would rather
I'm using a Java class library that is in many ways incomplete: there are
I'm sure this is something that comes up regularly, but I don't know how
This is a real beginner question (I'm still learning the Java basics). I can
I can name three advantages to using double (or float ) instead of decimal
I would like some practical guidance on when I should use a Domain Specific
Moose::Manual::Attributes states: As an alternative to using a subroutine reference [for default], you can

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.