Adding generic object to generic list in C#

前端 未结 5 1270
长发绾君心
长发绾君心 2020-12-11 02:23

I have class where the relevant part looks like

class C {
    void Method(SomeClass obj) {
        list.Add(obj);
    }
    List l         


        
相关标签:
5条回答
  • 2020-12-11 02:37

    I don't know anything about Java's ? construct, but I think the following most closely preserves your existing syntax while also matching your description.

        class SomeClass<T>
        {
        }
    
        class C
        {
            void Add<T>(SomeClass<T> item)
            {
                Type type = typeof(SomeClass<T>);
                if (!list.ContainsKey(type))
                    list[type] = new List<SomeClass<T>>();
                var l = (List<SomeClass<T>>)list[type];
                l.Add(item);
            }
    
            public void Method<T>(SomeClass<T> obj)
            {
                Add(obj);
            }
            readonly Dictionary<Type, object> list = new Dictionary<Type, object>();
        }
    

    test it with the following:

        class Program
        {
            static void Main(string[] args)
            {
                var c = new C();
                var sc1 = new SomeClass<int>();
                var sc2 = new SomeClass<String>();
                c.Method(sc1);
                c.Method(sc2);
                c.Method(sc1);
                c.Method(sc2);
            }
        }
    
    0 讨论(0)
  • 2020-12-11 02:38

    To do what you want, you have two options.

    You can use List<object>, and handle objects. This will not be typesafe, and will have boxing/unboxing issues for value types, but it will work.

    Your other option is to use a generic constraint to limit to a base class or interface, and use a List<Interface>.

    0 讨论(0)
  • 2020-12-11 02:38

    Personally, I would do this where possible; move the generic parameter from the method, to the class.

    class C<T> {
        void Method(SomeClass<T> obj) {
            list.Add(obj);
        }
        List<?> list = new List<?>();
    }
    

    If your generic list is a member, it stands to reason that the class should be constructed with this in mind. It is hard for us to suggest the best pattern without more usage context for the class.

    0 讨论(0)
  • 2020-12-11 02:41

    I don't think you can do this in C#... you would have to add the type parameter to the class:

    class C<T> {
        void Method(SomeClass<T> obj) {
            list.Add(obj);
        }
        List<SomeClass<T>> list = new List<SomeClass<T>>();
    }
    

    The other option would be to use an interface:

    class C {
    
        void Method<T>(T obj)
             where T : ISomeClass {
            list.Add(obj);
        }
        List<ISomeClass> list = new List<ISomeClass>();
    }
    
    0 讨论(0)
  • 2020-12-11 02:47

    Unfortunately, there is no direct equivalent in C# 3.0 as generics are invariant. You'll be able to do something like this in a graceful manner using C# 4.0 safe co/contra-variance feature. To workaround it, you could inherit SomeClass<T> from a nongeneric base and create a List<BaseClass> instead. If each instance of the class should hold only one type, you could make the class itself generic and set the type parameter there.

    0 讨论(0)
提交回复
热议问题