OK, the last one is never going to work: unless a class specifically implements a ToString override method the default
object
is used - which returns the fully qualified name of the type, not anything to do with the content.
So even a simple List will give you nothing useful:
List<int> myList = new List<int> { 1, 2, 3 };
Console.WriteLine(myList.ToString());
Will only give you:
System.Collections.Generic.List`1[System.Int32]
The others return exactly what you asked them to: they went through the entire DataTable, extracted the "ATTRITION_RATE" column values, and put them into an anonymous type collection - in the first case you converted that to a List, in the second you didn't.
If you want a single value from a collection rather than a new collection of items, then don't use
Select
- use
FirstOrDefault[
^] if you have a condition, or just get the data directly:
double value = myDataTable.Rows[0].Field<double>("ATTRITION_RATE");