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:
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.
CodePudding user response:
From the comments:
Just to be on the safe side, because I noticed the Count is a
int
but not auint
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 anint
(akaInt32
) property instead of auint
(orUInt32
) property is because theList<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
- Ostensibly, redistributable and reusable libraries should only use CLS-approved data-types and should avoid using non-CLS-compliant data-types.
- 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.
- So I think we can finally stop using CA1014.