/* * DynamORM - Dynamic Object-Relational Mapping library. * Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ using System; using System.Collections.Generic; namespace DynamORM.Helpers { /// Class contains unclassified extensions. internal static class UnclassifiedExtensions { /// Easy way to use conditional value. /// Includes . /// Input object type to check. /// Result type. /// The object to check. /// The select function. /// The else value. /// Selected value or default value. /// It lets you do this: /// var lname = thingy.NullOr(t => t.Name).NullOr(n => n.ToLower()); /// which is more fluent and (IMO) easier to read than this: /// var lname = (thingy != null ? thingy.Name : null) != null ? thingy.Name.ToLower() : null; /// public static R NullOr(this T obj, Func func, R elseValue = default(R)) where T : class { return obj != null && obj != DBNull.Value ? func(obj) : elseValue; } /// Easy way to use conditional value. /// Includes . /// Input object type to check. /// Result type. /// The object to check. /// The select function. /// The else value function. /// Selected value or default value. /// It lets you do this: /// var lname = thingy.NullOr(t => t.Name).NullOr(n => n.ToLower()); /// which is more fluent and (IMO) easier to read than this: /// var lname = (thingy != null ? thingy.Name : null) != null ? thingy.Name.ToLower() : null; /// public static R NullOrFn(this T obj, Func func, Func elseFunc = null) where T : class { // Old if to avoid recurency. return obj != null && obj != DBNull.Value ? func(obj) : elseFunc != null ? elseFunc() : default(R); } #if !NET6_0_OR_GREATER /// Simple distinct by selector extension. /// The enumerator of elements distinct by specified selector. /// Source collection. /// Distinct key selector. /// The enumerable element type parameter. /// The selector type parameter. public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector) { HashSet seenKeys = new HashSet(); foreach (R element in source) if (seenKeys.Add(keySelector(element))) yield return element; } #endif } }