由于属性是String,但您想对其进行数字排序,可能最好的方法是在您的类上实现IComparable,然后将您的自定义排序代码放入CompareTo 方法中。那么就不用每次想要对列表进行排序时都编写更复杂的 Lambda 语句,只需调用列表上的Sort() 方法即可。
您还可以处理FileName 属性不包含下划线或为null 的情况,而不是在OrderBy 代码中出现异常(大多数其他答案都会发生这种情况)。
我还进行了一些其他更改 - 覆盖 ToString 方法,以便您可以轻松地将值显示到控制台窗口,并为 FileName 属性使用自动属性语法,以便我们可以删除支持字段:
class xxx : IComparable<xxx>
{
public string FileName { get; set; }
public int CompareTo(xxx other)
{
// Short circuit if any object is null, if the
// Filenames equal each other, or they're empty
if (other == null) return 1;
if (FileName == null) return (other.FileName == null) ? 0 : -1;
if (other.FileName == null) return 1;
if (FileName.Equals(other.FileName)) return 0;
if (string.IsNullOrWhiteSpace(FileName))
return (string.IsNullOrWhiteSpace(other.FileName)) ? 0 : -1;
if (string.IsNullOrWhiteSpace(other.FileName)) return 1;
// Next, try to get the numeric portion of the string to compare
int thisIndex;
int otherIndex;
var thisSuccess = int.TryParse(FileName.Split('_')[0], out thisIndex);
var otherSuccess = int.TryParse(other.FileName.Split('_')[0], out otherIndex);
// If we couldn't get the numeric portion of the string, use int.MaxValue
if (!thisSuccess)
{
// If neither has a numeric portion, just use default string comparison
if (!otherSuccess) return FileName.CompareTo(other.FileName);
thisIndex = int.MaxValue;
}
if (!otherSuccess) otherIndex = int.MaxValue;
// Return the comparison of the numeric portion of the two filenames
return thisIndex.CompareTo(otherIndex);
}
public override string ToString()
{
return FileName;
}
}
现在,您只需拨打名单上的Sort:
List<xxx> list = new List<xxx>
{
new xxx {FileName = "13_a"},
new xxx {FileName = "8_a"},
new xxx {FileName = null},
new xxx {FileName = "1_a"},
new xxx {FileName = "zinvalid"},
new xxx {FileName = "2_a"},
new xxx {FileName = ""},
new xxx {FileName = "invalid"}
};
list.Sort();
Console.WriteLine(string.Join("\n", list));
// Output (note the first two are the empty string and the null value):
//
//
// 1_a
// 2_a
// 8_a
// 13_a
// invalid
// zinvalid