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); // -1
Converts 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); // -1
Creates 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); // true
Returns 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.Monday
Converts 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.Unknown
These 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")); // true
It 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 2020
The MIT license