This is a collection of small and useful extension methods for C#.
To use it just add using Clave.ExtensionMethods; at the top of the file
Join an enumerable of strings
var strings = new[] {"a", "b", "c"};
strings.Join(" "); // "a b c"Concatenate strings using space, triming away extra spaces
"a".ConcatWithSpace("b", "c"); // "a b c"
"a".ConcatWithSpace(" b ", " ", "c"); // "a b c"
// it also works on enumerables
new[]{"a", "b", "c"}.JoinWithSpace()Concatenate strings using space, triming away extra spaces
"a".ConcatWithComma("b", "c"); // "a, b, c"
"a".ConcatWithComma(" b ", " ", "c"); // "a, b, c"
// it also works on enumerables
new[]{"a", "b", "c"}.JoinWithComma()Converts a string to null if it is empty, useful together with the ?? operator
someString.ToNullIfEmpty() ?? "defaultValue";Converts a string to null if it is empty or only contains white space characters, useful together with the ?? operator
someString.ToNullIfWhiteSpace() ?? "defaultValue";Removes a prefix of a string if it is present
"something".SkipPrefix("some"); // "thing"Converts a string to an int. If it fails it returns the fallback value, which defaults to 0.
"123".ToInt(); // 123
"foo".ToInt(); // 0
"foo".ToInt(-1); // -1Converts a string to an decimal. If it fails it returns the fallback value, which defaults to 0.
"123.45".ToDecimal(); // 123.45
"foo".ToDecimal(); // 0
"foo".ToDecimal(-1); // -1Creates an enumerable with only one value
var enumerable = "something".Only();Creates an enumerable of one or more values
var enumerable = "some".And("thing", "else");Returns true if the list is empty, or if nothing matches the predicate
new string[0].NotAny(); // true
new []{"a", "b", "c"}.NotAny(string.IsNullOrEmpty); // trueReturns only the items that don't match the predicate
new []{"a", "", "c"}.WhereNot(string.IsNullOrEmpty); // "a", "c"Returns only the items that are not null
new []{"a", null, "c"}.WhereNotNull(); // "a", "c"
// this also works with a predicate
new []{new Foo("a"), new Foo(null), new Foo("c")}.WhereNotNull(f => f.Value); // "a", "c"Returns an IReadOnlyCollection, does nothing if the type is already an IReadOnlyCollection
"a".And("b", "c").ToReadOnlyCollection();
new []{"a", "b", "c"}.ToReadOnlyCollection();Returns an IReadOnlyList, does nothing if the type is already an IReadOnlyList
"a".And("b", "c").ToReadOnlyList();
new []{"a", "b", "c"}.ToReadOnlyList();Returns only the entries with a distinct key
new []{new Foo("a"), new Foo("a"), new Foo("c")}.DistinctBy(f => f.Value); // "a", "c"This uses the Compare<T> utility, described below.
Groups by a property in the key
new []{new Foo("a1"), new Foo("a2"), new Foo("b1"), new Foo("b2")}.GroupByProp(s => s.Prop, s => s[0]); // ["a1", "a2"], ["b1", "b2"]This uses the Compare<T> utility, described below.
Returns only the items that are not in the second set, using the selector
new []{new Foo("a"), new Foo("b"), new Foo("c")}.ExceptBy(new []{new Foo("b")}, f => f.Value); // "a", "c"This uses the Compare<T> utility, described below.
Zip together two enumerables and return a tuple of the entries
foreach(var (a, b) in listA.Zip(listB))
{
// ...
}Join together two enumerables using two key selectors and return a tuple of the entries
foreach(var (a, b) in listA.Join(listB, a => a.Id, b => b.Id))
{
// ...
}Call a function with the value. Very useful if you want to use optional chaining
valueThatMightBeNull?.Pipe(FuncThatNeedsValue);
arg1.Pipe(Func2, arg2);
arg1.Pipe(Func3, arg2, arg3);This is a useful way to get empty immutable objects. Since they are immutable the same empty instance can be reused every time.
Returns an empty IReadOnlyCollection
Empty.ReadOnlyCollection<string>();Returns an empty IReadOnlyList
Empty.ReadOnlyList<string>();Returns an empty Array
Empty.Array<string>();Converts a string to an enum, throws exception if it is an unknown string
"Monday".ToEnum<Weekday>(); // Weekday.MondayConverts a string to an enum, uses the default value if it is an unknown string
"Monday".ToEnumOrDefault(Weekday.Unknown); // Weekday.Monday
"BlaBla".ToEnumOrDefault(Weekday.Unknown); // Weekday.UnknownThese are magical extension methods that allow you to do useful magic.
To use it just add using Clave.ExtensionMethods.Magic; at the top of the file
This will add all the items in a list to another list
var list = new List<string>
{
"some",
GetStringList(),
"thing"
}This lets you await several tasks without using Task.WhenAll
await DoSomethingAsync().And(DoSomethingElseAsync(), AtTheSameTimeAsync());This is a utility for creating an IEqualityComparer on the fly
var yearComparer = Compare<DateTime>.Using(date => date.Year);
yearComparer.Equals(DateTime.Parse("2019-02-03"), DateTime.Parse("2019-08-19")); // trueIt can be used anywhere that expects an IEqualityComparer, for example .Distinct() and even Dictionary.
var dictionary = new Dictionary<DateTime, string>(yearComparer)
{
[DateTime.Parse("2019-02-06")] = "year 1",
[DateTime.Parse("2020-08-12")] = "year 2",
};
dictionary[DateTime.Now]; // "year 1" in 1019, "year 2" in 2020The MIT license