Home > OS >  Why is List<T>.Count a signed int? Can List<T>.Count ever be negative?
Why is List<T>.Count a signed int? Can List<T>.Count ever be negative?

Time:09-26

public class List<T>
{
     public int Count
        {
            get;
        }
}

I noticed Count is an int, will the result be less than 0?

If Count could be less than 0, I have to write that:

if(myList.Count < 1)
{
  
}

otherwise I can write that:

if(myList.Count == 0)
{
  
}

CodePudding user response:

No, the reference source (which only apply for .NET Framework) for that property is

public int Count {
   get {
       Contract.Ensures(Contract.Result<int>() >= 0);
       return _size; 
   }
}

which due to how Contract.Ensures works, guarantee it will never return less than zero.

As for .NET Core, that property is simply

public int Count => _size;

_size itself can't ever get below zero according to all the assignments in the code.

CodePudding user response:

From the comments:

Just to be on the safe side, because I noticed the Count is a int but not a uint

TL;DR:

When the List<T> class was designed, Microsoft's .NET class library design rules meant that UInt32 (aka uint) could not be used for any public members, so instead Int32 (aka int) was used.


Longer answer:

  • The reason why Count is an int (aka Int32) property instead of a uint (or UInt32) property is because the List<T> type was defined when the Common Language Specification (the "CLS") was still being respected by Microsoft.
    • Ostensibly, redistributable and reusable libraries should only use CLS-approved data-types and should avoid using non-CLS-compliant data-types.
      • Int32 is CLS-compliant.
      • UInt32 is not CLS-compliant.
    • The CLS exists because (at the time, around 2000-2005) Microsoft had this grand design for using .NET/CLR as the runtime and underlying type-system for many radically different programming languages - not just C# and VB.NET, but also Java (yup), OCaml-style functional languages like F#, and even JavaScript, Python, and PHP.
    • ...and many of those languages simply don't support unsigned integer types; in-fact, high-profile languages like Java still don't support unsigned types.
    • ...so in order to accommodate languages used by masochists, like Java, the main .NET class library had to be designed with restrictions on the possible data-types they could use, which means they have to use signed integers to represent unsigned values.
  • Since .NET Core was released, I don't believe there has been any official deprecation of the Common Language Specification, but even if Microsoft hasn't officially abandoned it, the rest of the .NET ecosystem seems to have.

CodePudding user response:

Of course it can, why even ask. Here is some blasphemy:

[TestFixture]
public class TotalGarbageTests
{
    [Test]
    public void Blasphemy()
    {
        var list = new List<int>();
        list.GetType().GetField("_size", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(list, -666);
        Assert.AreEqual(-666, list.Count);
    }
}

PS Now you are probably corrupted by knowledge, but meh, whatever.

  •  Tags:  
  • c#
  • Related