C#: System.Object vs Generics

前端 未结 8 875
别那么骄傲
别那么骄傲 2020-11-30 05:48

I\'m having a hard time understanding when to use Object (boxing/unboxing) vs when to use generics.

For example:

public class Stack 
{
    int positi         


        
相关标签:
8条回答
  • 2020-11-30 06:17

    While there are times when you will want to use a non-generic collection (think caching, for instance), you almost always have collections of homogenous objects not heterogenous objects. For a homogenous collection, even if it is a collection of variants of base type or interface, it's always better to use generics. This will save you from having to cast the result as the real type before you can use it. Using generics makes your code more efficient and readable because you can omit the code to do the cast.

    0 讨论(0)
  • 2020-11-30 06:17

    It all depends on what you need in the long run.

    Unlike most answers here, I won't say "always use generics" because sometimes you do need to mix cats with cucumbers.

    By all means, try to stick with generics for all the reasons already given in the other answers, for example if you need to combine cats and dogs create base class Mammal and have Stack<Mamal>.

    But when you really need to support every possible type, don't be afraid to use objects, they don't bite unless you're mistreating them. :)

    0 讨论(0)
  • 2020-11-30 06:20

    Generics are always preferred if possible.

    Aside from performance, Generics allow you to make guarantees about the types of objects that you're working with.

    The main reason this is preferred to casting is that the compiler knows what type the object is, and so it can give you compile errors that you find right away instead of runtime errors that might only happen under certain scenarios that you didn't test.

    0 讨论(0)
  • 2020-11-30 06:21

    Always use generics! Using object's results in cast operations and boxing/unboxing of value-types. Because of these reasons generics are faster and more elegant (no casting). And - the main reason - you won't get InvalidCastExceptions using generics.

    So, generics are faster and errors are visible at compile-time. System.Object means runtime exceptions and casting which in general results in lower performance (sometimes MUCH lower).

    0 讨论(0)
  • With the object type, as you say you need to perform boxing and unboxing, which gets tedious very quickly. With generics, there's no need for that.

    Also, I'd rather be more specific as to what kind of objects a class can work with and generics provides a great basis for that. Why mix unrelated data types in the first place? Your particular example of a stack emphasizes the benefit of generics over the basic object data type.

    // This stack should only contain integers and not strings or floats or bools
    Stack<int> intStack = new Stack<int>();
    intStack.Push(1);
    

    Remember that with generics you can specify interfaces so your class can interact with objects of many different classes, provided they all implement the same interface.

    0 讨论(0)
  • 2020-11-30 06:27

    Generics are not golden hammer. In cases where your activity naturally is non-generic, use good old object. One such case - caching. Cache naturally can hold different types. I've recently seen this implementation of cache wrapper

    void AddCacheItem<T>(string key, T item, int duration, ICacheItemExpiration expiration)
    {
        . . . . . . .
        CacheManager.Add(cacheKey, item, ..... 
    }
    

    Question: what for, if CacheManager takes object?

    Then there was real havoc in Get

    public virtual T GetCacheItem<T>(string cacheKey)
    {
        return (T)CacheManager.GetData(cacheKey); // <-- problem code
    }
    

    The problem above is that value type will crash.

    I mended the method by adding this

    public T GetCacheItem<T>(string cacheKey) where T : class
    

    Because I like idea of doing this

    var x = GetCacheItem<Person>("X")?
    string name = x?.FullName;
    

    But I added new method, which will allow to take value types as well

    public object GetCacheItem(string cacheKey)
    

    The bottom line, there is usage for object, especially when storing different types in collection. Or when you have compositions where completely arbitrary and unrelated objects can exist when you need to consume them based on type.

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