I have some bells in my database with the same number. I want to get all of them without duplication. I created a compare class to do this work, but the execution of the function causes a big delay from the function without distinct, from 0.6 sec to 3.2 sec!
Am I doing it right or do I have to use another method?
reg.AddRange(
(from a in this.dataContext.reglements
join b in this.dataContext.Clients on a.Id_client equals b.Id
where a.date_v <= datefin && a.date_v >= datedeb
where a.Id_client == b.Id
orderby a.date_v descending
select new Class_reglement
{
nom = b.Nom,
code = b.code,
Numf = a.Numf,
})
.AsEnumerable()
.Distinct(new Compare())
.ToList());
class Compare : IEqualityComparer<Class_reglement>
{
public bool Equals(Class_reglement x, Class_reglement y)
{
if (x.Numf == y.Numf)
{
return true;
}
else { return false; }
}
public int GetHashCode(Class_reglement codeh)
{
return 0;
}
}
Your GetHashCode implementation always returns the same value. Distinct relies on a good hash function to work efficiently because it internally builds a hash table.
When implementing interfaces of classes it is important to read the documentation, to know which contract you’re supposed to implement.1
In your code, the solution is to forward GetHashCode to Class_reglement.Numf.GetHashCode and implement it appropriately there.
Apart from that, your Equals method is full of unnecessary code. It could be rewritten as follows (same semantics, ¼ of the code, more readable):
public bool Equals(Class_reglement x, Class_reglement y)
{
return x.Numf == y.Numf;
}
Lastly, the ToList call is unnecessary and time-consuming: AddRange accepts any IEnumerable so conversion to a List isn’t required. AsEnumerable is also redundant here since processing the result in AddRange will cause this anyway.
1 Writing code without knowing what it actually does is called cargo cult programming. It’s a surprisingly widespread practice. It fundamentally doesn’t work.
Try This code:
public class GenericCompare<T> : IEqualityComparer<T> where T : class
{
private Func<T, object> _expr { get; set; }
public GenericCompare(Func<T, object> expr)
{
this._expr = expr;
}
public bool Equals(T x, T y)
{
var first = _expr.Invoke(x);
var sec = _expr.Invoke(y);
if (first != null && first.Equals(sec))
return true;
else
return false;
}
public int GetHashCode(T obj)
{
return obj.GetHashCode();
}
}
Example of its use would be
collection = collection
.Except(ExistedDataEles, new GenericCompare<DataEle>(x=>x.Id))
.ToList();
If you want a generic solution that creates an IEqualityComparer for your class based on a property (which acts as a key) of that class have a look at this:
public class KeyBasedEqualityComparer<T, TKey> : IEqualityComparer<T>
{
private readonly Func<T, TKey> _keyGetter;
public KeyBasedEqualityComparer(Func<T, TKey> keyGetter)
{
if (default(T) == null)
{
_keyGetter = (x) => x == null ? default : keyGetter(x);
}
else
{
_keyGetter = keyGetter;
}
}
public bool Equals(T x, T y)
{
return EqualityComparer<TKey>.Default.Equals(_keyGetter(x), _keyGetter(y));
}
public int GetHashCode(T obj)
{
TKey key = _keyGetter(obj);
return key == null ? 0 : key.GetHashCode();
}
}
public static class KeyBasedEqualityComparer<T>
{
public static KeyBasedEqualityComparer<T, TKey> Create<TKey>(Func<T, TKey> keyGetter)
{
return new KeyBasedEqualityComparer<T, TKey>(keyGetter);
}
}
For better performance with structs there isn't any boxing.
Usage is like this:
IEqualityComparer<Class_reglement> equalityComparer =
KeyBasedEqualityComparer<Class_reglement>.Create(x => x.Numf);
Just code, with implementation of GetHashCode and NULL validation:
public class Class_reglementComparer : IEqualityComparer<Class_reglement>
{
public bool Equals(Class_reglement x, Class_reglement y)
{
if (x is null || y is null))
return false;
return x.Numf == y.Numf;
}
public int GetHashCode(Class_reglement product)
{
//Check whether the object is null
if (product is null) return 0;
//Get hash code for the Numf field if it is not null.
int hashNumf = product.hashNumf == null ? 0 : product.hashNumf.GetHashCode();
return hashNumf;
}
}
Example:
list of Class_reglement distinct by Numf
List<Class_reglement> items = items.Distinct(new Class_reglementComparer());
The purpose of this answer is to improve on previous answers by:
making the lambda expression optional in the constructor so that full object equality can be checked by default, not just on one of the properties.
operating on different types of classes, even complex types including sub-objects or nested lists. And not only on simple classes comprising only primitive type properties.
Not taking into account possible list container differences.
Here, you'll find a first simple code sample that works only on simple types (the ones composed only by primitif properties), and a second one that is complete (for a wider range of classes and complex types).
Here is my 2 pennies try:
public class GenericEqualityComparer<T> : IEqualityComparer<T> where T : class
{
private Func<T, object> _expr { get; set; }
public GenericEqualityComparer() => _expr = null;
public GenericEqualityComparer(Func<T, object> expr) => _expr = expr;
public bool Equals(T x, T y)
{
var first = _expr?.Invoke(x) ?? x;
var sec = _expr?.Invoke(y) ?? y;
if (first == null && sec == null)
return true;
if (first != null && first.Equals(sec))
return true;
var typeProperties = typeof(T).GetProperties();
foreach (var prop in typeProperties)
{
var firstPropVal = prop.GetValue(first, null);
var secPropVal = prop.GetValue(sec, null);
if (firstPropVal != null && !firstPropVal.Equals(secPropVal))
return false;
}
return true;
}
public int GetHashCode(T obj) =>
_expr?.Invoke(obj).GetHashCode() ?? obj.GetHashCode();
}
I know we can still optimize it (and maybe use a recursive?)..
But that is working like a charm without this much complexity and on a wide range of classes. ;)
Edit: After a day, here is my $10 attempt:
First, in a separate static extension class, you'll need:
public static class CollectionExtensions
{
public static bool HasSameLengthThan<T>(this IEnumerable<T> list, IEnumerable<T> expected)
{
if (list.IsNullOrEmptyCollection() && expected.IsNullOrEmptyCollection())
return true;
if ((list.IsNullOrEmptyCollection() && !expected.IsNullOrEmptyCollection()) || (!list.IsNullOrEmptyCollection() && expected.IsNullOrEmptyCollection()))
return false;
return list.Count() == expected.Count();
}
/// <summary>
/// Used to find out if a collection is empty or if it contains no elements.
/// </summary>
/// <typeparam name="T">Type of the collection's items.</typeparam>
/// <param name="list">Collection of items to test.</param>
/// <returns><c>true</c> if the collection is <c>null</c> or empty (without items), <c>false</c> otherwise.</returns>
public static bool IsNullOrEmptyCollection<T>(this IEnumerable<T> list) => list == null || !list.Any();
}
Then, here is the updated class that works on a wider range of classes:
public class GenericComparer<T> : IEqualityComparer<T> where T : class
{
private Func<T, object> _expr { get; set; }
public GenericComparer() => _expr = null;
public GenericComparer(Func<T, object> expr) => _expr = expr;
public bool Equals(T x, T y)
{
var first = _expr?.Invoke(x) ?? x;
var sec = _expr?.Invoke(y) ?? y;
if (ObjEquals(first, sec))
return true;
var typeProperties = typeof(T).GetProperties();
foreach (var prop in typeProperties)
{
var firstPropVal = prop.GetValue(first, null);
var secPropVal = prop.GetValue(sec, null);
if (!ObjEquals(firstPropVal, secPropVal))
{
var propType = prop.PropertyType;
if (IsEnumerableType(propType) && firstPropVal is IEnumerable && !ArrayEquals(firstPropVal, secPropVal))
return false;
if (propType.IsClass)
{
if (!DeepEqualsFromObj(firstPropVal, secPropVal, propType))
return false;
if (!DeepObjEquals(firstPropVal, secPropVal))
return false;
}
}
}
return true;
}
public int GetHashCode(T obj) =>
_expr?.Invoke(obj).GetHashCode() ?? obj.GetHashCode();
#region Private Helpers
private bool DeepObjEquals(object x, object y) =>
new GenericComparer<object>().Equals(x, y);
private bool DeepEquals<U>(U x, U y) where U : class =>
new GenericComparer<U>().Equals(x, y);
private bool DeepEqualsFromObj(object x, object y, Type type)
{
dynamic a = Convert.ChangeType(x, type);
dynamic b = Convert.ChangeType(y, type);
return DeepEquals(a, b);
}
private bool IsEnumerableType(Type type) =>
type.GetInterface(nameof(IEnumerable)) != null;
private bool ObjEquals(object x, object y)
{
if (x == null && y == null) return true;
return x != null && x.Equals(y);
}
private bool ArrayEquals(object x, object y)
{
var firstList = new List<object>((IEnumerable<object>)x);
var secList = new List<object>((IEnumerable<object>)y);
if (!firstList.HasSameLengthThan(secList))
return false;
var elementType = firstList?.FirstOrDefault()?.GetType();
int cpt = 0;
foreach (var e in firstList)
{
if (!DeepEqualsFromObj(e, secList[cpt++], elementType))
return false;
}
return true;
}
#endregion Private Helpers
We can still optimize it but it worth give it a try ^^.
The inclusion of your comparison class (or more specifically the AsEnumerable call you needed to use to get it to work) meant that the sorting logic went from being based on the database server to being on the database client (your application). This meant that your client now needs to retrieve and then process a larger number of records, which will always be less efficient that performing the lookup on the database where the approprate indexes can be used.
You should try to develop a where clause that satisfies your requirements instead, see Using an IEqualityComparer with a LINQ to Entities Except clause for more details.
IEquatable<T> can be a much easier way to do this with modern frameworks.
You get a nice simple bool Equals(T other) function and there's no messing around with casting or creating a separate class.
public class Person : IEquatable<Person>
{
public Person(string name, string hometown)
{
this.Name = name;
this.Hometown = hometown;
}
public string Name { get; set; }
public string Hometown { get; set; }
// can't get much simpler than this!
public bool Equals(Person other)
{
return this.Name == other.Name && this.Hometown == other.Hometown;
}
public override int GetHashCode()
{
return Name.GetHashCode(); // see other links for hashcode guidance
}
}
Note you DO have to implement GetHashCode if using this in a dictionary or with something like Distinct.
PS. I don't think any custom Equals methods work with entity framework directly on the database side (I think you know this because you do AsEnumerable) but this is a much simpler method to do a simple Equals for the general case.
If things don't seem to be working (such as duplicate key errors when doing ToDictionary) put a breakpoint inside Equals to make sure it's being hit and make sure you have GetHashCode defined (with override keyword).
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
Let's make a list of answers where you post your excellent and favorite extension methods.
The requirement is that the full code must be posted and a example and an explanation on how to use it.
Based on the high interest in this topic I have setup an Open Source Project called extensionoverflow on Codeplex.
Please mark your answers with an acceptance to put the code in the Codeplex project.
Please post the full sourcecode and not a link.
Codeplex News:
24.08.2010 The Codeplex page is now here: http://extensionoverflow.codeplex.com/
11.11.2008 XmlSerialize / XmlDeserialize is now Implemented and Unit Tested.
11.11.2008 There is still room for more developers. ;-) Join NOW!
11.11.2008 Third contributer joined ExtensionOverflow, welcome to BKristensen
11.11.2008 FormatWith is now Implemented and Unit Tested.
09.11.2008 Second contributer joined ExtensionOverflow. welcome to chakrit.
09.11.2008 We need more developers. ;-)
09.11.2008 ThrowIfArgumentIsNull in now Implemented and Unit Tested on Codeplex.
public static bool In<T>(this T source, params T[] list)
{
if(null==source) throw new ArgumentNullException("source");
return list.Contains(source);
}
Allows me to replace:
if(reallyLongIntegerVariableName == 1 ||
reallyLongIntegerVariableName == 6 ||
reallyLongIntegerVariableName == 9 ||
reallyLongIntegerVariableName == 11)
{
// do something....
}
and
if(reallyLongStringVariableName == "string1" ||
reallyLongStringVariableName == "string2" ||
reallyLongStringVariableName == "string3")
{
// do something....
}
and
if(reallyLongMethodParameterName == SomeEnum.Value1 ||
reallyLongMethodParameterName == SomeEnum.Value2 ||
reallyLongMethodParameterName == SomeEnum.Value3 ||
reallyLongMethodParameterName == SomeEnum.Value4)
{
// do something....
}
With:
if(reallyLongIntegerVariableName.In(1,6,9,11))
{
// do something....
}
and
if(reallyLongStringVariableName.In("string1","string2","string3"))
{
// do something....
}
and
if(reallyLongMethodParameterName.In(SomeEnum.Value1, SomeEnum.Value2, SomeEnum.Value3, SomeEnum.Value4)
{
// do something....
}
I have various extension methods in my MiscUtil project (full source is available there - I'm not going to repeat it here). My favourites, some of which involve other classes (such as ranges):
Date and time stuff - mostly for unit tests. Not sure I'd use them in production :)
var birthday = 19.June(1976);
var workingDay = 7.Hours() + 30.Minutes();
Ranges and stepping - massive thanks to Marc Gravell for his operator stuff to make this possible:
var evenNaturals = 2.To(int.MaxValue).Step(2);
var daysSinceBirth = birthday.To(DateTime.Today).Step(1.Days());
Comparisons:
var myComparer = ProjectionComparer.Create(Person p => p.Name);
var next = myComparer.ThenBy(p => p.Age);
var reversed = myComparer.Reverse();
Argument checking:
x.ThrowIfNull("x");
LINQ to XML applied to anonymous types (or other types with appropriate properties):
// <Name>Jon</Name><Age>32</Age>
new { Name="Jon", Age=32}.ToXElements();
// Name="Jon" Age="32" (as XAttributes, obviously)
new { Name="Jon", Age=32}.ToXAttributes()
Push LINQ - would take too long to explain here, but search for it.
string.Format shortcut:
public static class StringExtensions
{
// Enable quick and more natural string.Format calls
public static string F(this string s, params object[] args)
{
return string.Format(s, args);
}
}
Example:
var s = "The co-ordinate is ({0}, {1})".F(point.X, point.Y);
For quick copy-and-paste go here.
Don't you find it more natural to type "some string".F("param") instead of string.Format("some string", "param") ?
For a more readable name, try one of these suggestion:
s = "Hello {0} world {1}!".Fmt("Stack", "Overflow");
s = "Hello {0} world {1}!".FormatBy("Stack", "Overflow");
s = "Hello {0} world {1}!".FormatWith("Stack", "Overflow");
s = "Hello {0} world {1}!".Display("Stack", "Overflow");
s = "Hello {0} world {1}!".With("Stack", "Overflow");
..
Are these any use?
public static bool CoinToss(this Random rng)
{
return rng.Next(2) == 0;
}
public static T OneOf<T>(this Random rng, params T[] things)
{
return things[rng.Next(things.Length)];
}
Random rand;
bool luckyDay = rand.CoinToss();
string babyName = rand.OneOf("John", "George", "Radio XBR74 ROCKS!");
public static class ComparableExtensions
{
public static bool Between<T>(this T actual, T lower, T upper) where T : IComparable<T>
{
return actual.CompareTo(lower) >= 0 && actual.CompareTo(upper) < 0;
}
}
Example:
if (myNumber.Between(3,7))
{
// ....
}
The extension method:
public static void AddRange<T, S>(this ICollection<T> list, params S[] values)
where S : T
{
foreach (S value in values)
list.Add(value);
}
The method applies for all types and lets you add a range of items to a list as parameters.
Example:
var list = new List<Int32>();
list.AddRange(5, 4, 8, 4, 2);
By all means put this in the codeplex project.
Serializing / Deserializing objects to XML:
/// <summary>Serializes an object of type T in to an xml string</summary>
/// <typeparam name="T">Any class type</typeparam>
/// <param name="obj">Object to serialize</param>
/// <returns>A string that represents Xml, empty otherwise</returns>
public static string XmlSerialize<T>(this T obj) where T : class, new()
{
if (obj == null) throw new ArgumentNullException("obj");
var serializer = new XmlSerializer(typeof(T));
using (var writer = new StringWriter())
{
serializer.Serialize(writer, obj);
return writer.ToString();
}
}
/// <summary>Deserializes an xml string in to an object of Type T</summary>
/// <typeparam name="T">Any class type</typeparam>
/// <param name="xml">Xml as string to deserialize from</param>
/// <returns>A new object of type T is successful, null if failed</returns>
public static T XmlDeserialize<T>(this string xml) where T : class, new()
{
if (xml == null) throw new ArgumentNullException("xml");
var serializer = new XmlSerializer(typeof(T));
using (var reader = new StringReader(xml))
{
try { return (T)serializer.Deserialize(reader); }
catch { return null; } // Could not be deserialized to this type.
}
}
ForEach for IEnumerables
public static class FrameworkExtensions
{
// a map function
public static void ForEach<T>(this IEnumerable<T> #enum, Action<T> mapFunction)
{
foreach (var item in #enum) mapFunction(item);
}
}
Naive example:
var buttons = GetListOfButtons() as IEnumerable<Button>;
// click all buttons
buttons.ForEach(b => b.Click());
Cool example:
// no need to type the same assignment 3 times, just
// new[] up an array and use foreach + lambda
// everything is properly inferred by csc :-)
new { itemA, itemB, itemC }
.ForEach(item => {
item.Number = 1;
item.Str = "Hello World!";
});
Note:
This is not like Select because Select expects your function to return something as for transforming into another list.
ForEach simply allows you to execute something for each of the items without any transformations/data manipulation.
I made this so I can program in a more functional style and I was surprised that List has a ForEach while IEnumerable does not.
Put this in the codeplex project
My conversion extensions which allow you to do:
int i = myString.To<int>();
Here it is, as posted on TheSoftwareJedi.com
public static T To<T>(this IConvertible obj)
{
return (T)Convert.ChangeType(obj, typeof(T));
}
public static T ToOrDefault<T>
(this IConvertible obj)
{
try
{
return To<T>(obj);
}
catch
{
return default(T);
}
}
public static bool ToOrDefault<T>
(this IConvertible obj,
out T newObj)
{
try
{
newObj = To<T>(obj);
return true;
}
catch
{
newObj = default(T);
return false;
}
}
public static T ToOrOther<T>
(this IConvertible obj,
T other)
{
try
{
return To<T>obj);
}
catch
{
return other;
}
}
public static bool ToOrOther<T>
(this IConvertible obj,
out T newObj,
T other)
{
try
{
newObj = To<T>(obj);
return true;
}
catch
{
newObj = other;
return false;
}
}
public static T ToOrNull<T>
(this IConvertible obj)
where T : class
{
try
{
return To<T>(obj);
}
catch
{
return null;
}
}
public static bool ToOrNull<T>
(this IConvertible obj,
out T newObj)
where T : class
{
try
{
newObj = To<T>(obj);
return true;
}
catch
{
newObj = null;
return false;
}
}
You can ask for default (calls blank constructor or "0" for numerics) on failure, specify a "default" value (I call it "other"), or ask for null (where T : class). I've also provided both silent exception models, and a typical TryParse model that returns a bool indicating the action taken, and an out param holds the new value.
So our code can do things like this
int i = myString.To<int>();
string a = myInt.ToOrDefault<string>();
//note type inference
DateTime d = myString.ToOrOther(DateTime.MAX_VALUE);
double d;
//note type inference
bool didItGiveDefault = myString.ToOrDefault(out d);
string s = myDateTime.ToOrNull<string>();
I couldn't get Nullable types to roll into the whole thing very cleanly. I tried for about 20 minutes before I threw in the towel.
I have an extension method for logging exceptions:
public static void Log(this Exception obj)
{
//your logging logic here
}
And it is used like this:
try
{
//Your stuff here
}
catch(Exception ex)
{
ex.Log();
}
[sorry for posting twice; the 2nd one is better designed :-)]
public static class StringExtensions {
/// <summary>
/// Parses a string into an Enum
/// </summary>
/// <typeparam name="T">The type of the Enum</typeparam>
/// <param name="value">String value to parse</param>
/// <returns>The Enum corresponding to the stringExtensions</returns>
public static T EnumParse<T>(this string value) {
return StringExtensions.EnumParse<T>(value, false);
}
public static T EnumParse<T>(this string value, bool ignorecase) {
if (value == null) {
throw new ArgumentNullException("value");
}
value = value.Trim();
if (value.Length == 0) {
throw new ArgumentException("Must specify valid information for parsing in the string.", "value");
}
Type t = typeof(T);
if (!t.IsEnum) {
throw new ArgumentException("Type provided must be an Enum.", "T");
}
return (T)Enum.Parse(t, value, ignorecase);
}
}
Useful to parse a string into an Enum.
public enum TestEnum
{
Bar,
Test
}
public class Test
{
public void Test()
{
TestEnum foo = "Test".EnumParse<TestEnum>();
}
}
Credit goes to Scott Dorman
--- Edit for Codeplex project ---
I have asked Scott Dorman if he would mind us publishing his code in the Codeplex project. This is the reply I got from him:
Thanks for the heads-up on both the SO post and the CodePlex project. I have upvoted your answer on the question. Yes, the code is effectively in the public domain currently under the CodeProject Open License (http://www.codeproject.com/info/cpol10.aspx).
I have no problems with this being included in the CodePlex project, and if you want to add me to the project (username is sdorman) I will add that method plus some additional enum helper methods.
I find this one pretty useful:
public static class PaulaBean
{
private static String paula = "Brillant";
public static String GetPaula<T>(this T obj) {
return paula;
}
}
You may use it on CodePlex.
DateTimeExtensions
Examples:
DateTime firstDayOfMonth = DateTime.Now.First();
DateTime lastdayOfMonth = DateTime.Now.Last();
DateTime lastFridayInMonth = DateTime.Now.Last(DayOfWeek.Friday);
DateTime nextFriday = DateTime.Now.Next(DayOfWeek.Friday);
DateTime lunchTime = DateTime.Now.SetTime(11, 30);
DateTime noonOnFriday = DateTime.Now.Next(DayOfWeek.Friday).Noon();
DateTime secondMondayOfMonth = DateTime.Now.First(DayOfWeek.Monday).Next(DayOfWeek.Monday).Midnight();
gitorious.org/cadenza is a full library of some of the most useful extension methods I've seen.
Here is one I use frequently for presentation formatting.
public static string ToTitleCase(this string mText)
{
if (mText == null) return mText;
System.Globalization.CultureInfo cultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture;
System.Globalization.TextInfo textInfo = cultureInfo.TextInfo;
// TextInfo.ToTitleCase only operates on the string if is all lower case, otherwise it returns the string unchanged.
return textInfo.ToTitleCase(mText.ToLower());
}
Here's a to-and-from for Roman numerals. Not often used, but could be handy. Usage:
if ("IV".IsValidRomanNumeral())
{
// Do useful stuff with the number 4.
}
Console.WriteLine("MMMDCCCLXXXVIII".ParseRomanNumeral());
Console.WriteLine(3888.ToRomanNumeralString());
The source:
public static class RomanNumeralExtensions
{
private const int NumberOfRomanNumeralMaps = 13;
private static readonly Dictionary<string, int> romanNumerals =
new Dictionary<string, int>(NumberOfRomanNumeralMaps)
{
{ "M", 1000 },
{ "CM", 900 },
{ "D", 500 },
{ "CD", 400 },
{ "C", 100 },
{ "XC", 90 },
{ "L", 50 },
{ "XL", 40 },
{ "X", 10 },
{ "IX", 9 },
{ "V", 5 },
{ "IV", 4 },
{ "I", 1 }
};
private static readonly Regex validRomanNumeral = new Regex(
"^(?i:(?=[MDCLXVI])((M{0,3})((C[DM])|(D?C{0,3}))"
+ "?((X[LC])|(L?XX{0,2})|L)?((I[VX])|(V?(II{0,2}))|V)?))$",
RegexOptions.Compiled);
public static bool IsValidRomanNumeral(this string value)
{
return validRomanNumeral.IsMatch(value);
}
public static int ParseRomanNumeral(this string value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
value = value.ToUpperInvariant().Trim();
var length = value.Length;
if ((length == 0) || !value.IsValidRomanNumeral())
{
throw new ArgumentException("Empty or invalid Roman numeral string.", "value");
}
var total = 0;
var i = length;
while (i > 0)
{
var digit = romanNumerals[value[--i].ToString()];
if (i > 0)
{
var previousDigit = romanNumerals[value[i - 1].ToString()];
if (previousDigit < digit)
{
digit -= previousDigit;
i--;
}
}
total += digit;
}
return total;
}
public static string ToRomanNumeralString(this int value)
{
const int MinValue = 1;
const int MaxValue = 3999;
if ((value < MinValue) || (value > MaxValue))
{
throw new ArgumentOutOfRangeException("value", value, "Argument out of Roman numeral range.");
}
const int MaxRomanNumeralLength = 15;
var sb = new StringBuilder(MaxRomanNumeralLength);
foreach (var pair in romanNumerals)
{
while (value / pair.Value > 0)
{
sb.Append(pair.Key);
value -= pair.Value;
}
}
return sb.ToString();
}
}
A convenient way to deal with sizes:
public static class Extensions {
public static int K(this int value) {
return value * 1024;
}
public static int M(this int value) {
return value * 1024 * 1024;
}
}
public class Program {
public void Main() {
WSHttpContextBinding serviceMultipleTokenBinding = new WSHttpContextBinding() {
MaxBufferPoolSize = 2.M(), // instead of 2097152
MaxReceivedMessageSize = 64.K(), // instead of 65536
};
}
}
For Winform Controls:
/// <summary>
/// Returns whether the function is being executed during design time in Visual Studio.
/// </summary>
public static bool IsDesignTime(this Control control)
{
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
{
return true;
}
if (control.Site != null && control.Site.DesignMode)
{
return true;
}
var parent = control.Parent;
while (parent != null)
{
if (parent.Site != null && parent.Site.DesignMode)
{
return true;
}
parent = parent.Parent;
}
return false;
}
/// <summary>
/// Sets the DropDownWidth to ensure that no item's text is cut off.
/// </summary>
public static void SetDropDownWidth(this ComboBox comboBox)
{
var g = comboBox.CreateGraphics();
var font = comboBox.Font;
float maxWidth = 0;
foreach (var item in comboBox.Items)
{
maxWidth = Math.Max(maxWidth, g.MeasureString(item.ToString(), font).Width);
}
if (comboBox.Items.Count > comboBox.MaxDropDownItems)
{
maxWidth += SystemInformation.VerticalScrollBarWidth;
}
comboBox.DropDownWidth = Math.Max(comboBox.Width, Convert.ToInt32(maxWidth));
}
IsDesignTime Usage:
public class SomeForm : Form
{
public SomeForm()
{
InitializeComponent();
if (this.IsDesignTime())
{
return;
}
// Do something that makes the visual studio crash or hang if we're in design time,
// but any other time executes just fine
}
}
SetDropdownWidth Usage:
ComboBox cbo = new ComboBox { Width = 50 };
cbo.Items.Add("Short");
cbo.Items.Add("A little longer");
cbo.Items.Add("Holy cow, this is a really, really long item. How in the world will it fit?");
cbo.SetDropDownWidth();
I forgot to mention, feel free to use these on Codeplex...
The ThrowIfArgumentIsNull is a nice way to do that null check we all should do.
public static class Extensions
{
public static void ThrowIfArgumentIsNull<T>(this T obj, string parameterName) where T : class
{
if (obj == null) throw new ArgumentNullException(parameterName + " not allowed to be null");
}
}
Below is the way to use it and it works on all classes in your namespace or wherever you use the namespace its within.
internal class Test
{
public Test(string input1)
{
input1.ThrowIfArgumentIsNull("input1");
}
}
It's ok to use this code on the CodePlex project.
I miss the Visual Basic's With statement when moving to C#, so here it goes:
public static void With<T>(this T obj, Action<T> act) { act(obj); }
And here's how to use it in C#:
someVeryVeryLonggggVariableName.With(x => {
x.Int = 123;
x.Str = "Hello";
x.Str2 = " World!";
});
Saves a lot of typing!
Compare this to:
someVeryVeryLonggggVariableName.Int = 123;
someVeryVeryLonggggVariableName.Str = "Hello";
someVeryVeryLonggggVariableName.Str2 = " World!";
put in codeplex project
Takes a camelCaseWord or PascalCaseWord and "wordifies" it, ie camelCaseWord => camel Case Word
public static string Wordify( this string camelCaseWord )
{
// if the word is all upper, just return it
if( !Regex.IsMatch( camelCaseWord, "[a-z]" ) )
return camelCaseWord;
return string.Join( " ", Regex.Split( camelCaseWord, #"(?<!^)(?=[A-Z])" ) );
}
I often use it in conjuction with Capitalize
public static string Capitalize( this string word )
{
return word[0].ToString( ).ToUpper( ) + word.Substring( 1 );
}
Example usage
SomeEntityObject entity = DataAccessObject.GetSomeEntityObject( id );
List<PropertyInfo> properties = entity.GetType().GetPublicNonCollectionProperties( );
// wordify the property names to act as column headers for an html table or something
List<string> columns = properties.Select( p => p.Name.Capitalize( ).Wordify( ) ).ToList( );
Free to use in codeplex project
I found this one helpful
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> pSeq)
{
return pSeq ?? Enumerable.Empty<T>();
}
It removes the null check in the calling code. You could now do
MyList.EmptyIfNull().Where(....)
Convert a double to string formatted using the specified culture:
public static class ExtensionMethods
{
public static string ToCurrency(this double value, string cultureName)
{
CultureInfo currentCulture = new CultureInfo(cultureName);
return (string.Format(currentCulture, "{0:C}", value));
}
}
Example:
double test = 154.20;
string testString = test.ToCurrency("en-US"); // $154.20
Below is an extension method that adapts Rick Strahl's code (and the comments too) to stop you having to guess or read the byte order mark of a byte array or text file each time you convert it to a string.
The snippet allows you to simply do:
byte[] buffer = File.ReadAllBytes(#"C:\file.txt");
string content = buffer.GetString();
If you find any bugs please add to the comments. Feel free to include it in the Codeplex project.
public static class Extensions
{
/// <summary>
/// Converts a byte array to a string, using its byte order mark to convert it to the right encoding.
/// Original article: http://www.west-wind.com/WebLog/posts/197245.aspx
/// </summary>
/// <param name="buffer">An array of bytes to convert</param>
/// <returns>The byte as a string.</returns>
public static string GetString(this byte[] buffer)
{
if (buffer == null || buffer.Length == 0)
return "";
// Ansi as default
Encoding encoding = Encoding.Default;
/*
EF BB BF UTF-8
FF FE UTF-16 little endian
FE FF UTF-16 big endian
FF FE 00 00 UTF-32, little endian
00 00 FE FF UTF-32, big-endian
*/
if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf)
encoding = Encoding.UTF8;
else if (buffer[0] == 0xfe && buffer[1] == 0xff)
encoding = Encoding.Unicode;
else if (buffer[0] == 0xfe && buffer[1] == 0xff)
encoding = Encoding.BigEndianUnicode; // utf-16be
else if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff)
encoding = Encoding.UTF32;
else if (buffer[0] == 0x2b && buffer[1] == 0x2f && buffer[2] == 0x76)
encoding = Encoding.UTF7;
using (MemoryStream stream = new MemoryStream())
{
stream.Write(buffer, 0, buffer.Length);
stream.Seek(0, SeekOrigin.Begin);
using (StreamReader reader = new StreamReader(stream, encoding))
{
return reader.ReadToEnd();
}
}
}
}
Here's one I just created today.
// requires .NET 4
public static TReturn NullOr<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> func,
TReturn elseValue = default(TReturn)) where TIn : class
{ return obj != null ? func(obj) : elseValue; }
// versions for CLR 2, which doesn't support optional params
public static TReturn NullOr<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> func,
TReturn elseValue) where TIn : class
{ return obj != null ? func(obj) : elseValue; }
public static TReturn NullOr<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> func)
where TIn : class
{ return obj != null ? func(obj) : default(TReturn); }
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;
"Please mark your answers with an acceptance to put the code in the Codeplex project."
Why? All the Stuff on this site under CC-by-sa-2.5, so just put your Extension overflow Project under the same license and you can freely use it.
Anyway, here is a String.Reverse function, based on this question.
/// <summary>
/// Reverse a String
/// </summary>
/// <param name="input">The string to Reverse</param>
/// <returns>The reversed String</returns>
public static string Reverse(this string input)
{
char[] array = input.ToCharArray();
Array.Reverse(array);
return new string(array);
}
I got tired of tedious null-checking while pulling values from MySqlDataReader, so:
public static DateTime? GetNullableDateTime(this MySqlDataReader dr, string fieldName)
{
DateTime? nullDate = null;
return dr.IsDBNull(dr.GetOrdinal(fieldName)) ? nullDate : dr.GetDateTime(fieldName);
}
public static string GetNullableString(this MySqlDataReader dr, string fieldName)
{
return dr.IsDBNull(dr.GetOrdinal(fieldName)) ? String.Empty : dr.GetString(fieldName);
}
public static char? GetNullableChar(this MySqlDataReader dr, string fieldName)
{
char? nullChar = null;
return dr.IsDBNull(dr.GetOrdinal(fieldName)) ? nullChar : dr.GetChar(fieldName);
}
Of course this could be used with any SqlDataReader.
Both hangy and Joe had some good comments on how to do this, and I have since had an opportunity to implement something similar in a different context, so here is another version:
public static int? GetNullableInt32(this IDataRecord dr, int ordinal)
{
int? nullInt = null;
return dr.IsDBNull(ordinal) ? nullInt : dr.GetInt32(ordinal);
}
public static int? GetNullableInt32(this IDataRecord dr, string fieldname)
{
int ordinal = dr.GetOrdinal(fieldname);
return dr.GetNullableInt32(ordinal);
}
public static bool? GetNullableBoolean(this IDataRecord dr, int ordinal)
{
bool? nullBool = null;
return dr.IsDBNull(ordinal) ? nullBool : dr.GetBoolean(ordinal);
}
public static bool? GetNullableBoolean(this IDataRecord dr, string fieldname)
{
int ordinal = dr.GetOrdinal(fieldname);
return dr.GetNullableBoolean(ordinal);
}
It irritated me that LINQ gives me an OrderBy that takes a class implementing IComparer as an argument, but does not support passing in a simple anonymous comparer function. I rectified that.
This class creates an IComparer from your comparer function...
/// <summary>
/// Creates an <see cref="IComparer{T}"/> instance for the given
/// delegate function.
/// </summary>
internal class ComparerFactory<T> : IComparer<T>
{
public static IComparer<T> Create(Func<T, T, int> comparison)
{
return new ComparerFactory<T>(comparison);
}
private readonly Func<T, T, int> _comparison;
private ComparerFactory(Func<T, T, int> comparison)
{
_comparison = comparison;
}
#region IComparer<T> Members
public int Compare(T x, T y)
{
return _comparison(x, y);
}
#endregion
}
...and these extension methods expose my new OrderBy overloads on enumerables. I doubt this works for LINQ to SQL, but it's great for LINQ to Objects.
public static class EnumerableExtensions
{
/// <summary>
/// Sorts the elements of a sequence in ascending order by using a specified comparison delegate.
/// </summary>
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector,
Func<TKey, TKey, int> comparison)
{
var comparer = ComparerFactory<TKey>.Create(comparison);
return source.OrderBy(keySelector, comparer);
}
/// <summary>
/// Sorts the elements of a sequence in descending order by using a specified comparison delegate.
/// </summary>
public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector,
Func<TKey, TKey, int> comparison)
{
var comparer = ComparerFactory<TKey>.Create(comparison);
return source.OrderByDescending(keySelector, comparer);
}
}
You're welcome to put this on codeplex if you like.
This one is for MVC it adds the ability to generate a <label /> tag to the Html variable that is available in every ViewPage. Hopefully it will be of use to others trying to develop similar extensions.
Use:
<%= Html.Label("LabelId", "ForId", "Text")%>
Output:
<label id="LabelId" for="ForId">Text</label>
Code:
public static class HtmlHelperExtensions
{
public static string Label(this HtmlHelper Html, string #for, string text)
{
return Html.Label(null, #for, text);
}
public static string Label(this HtmlHelper Html, string #for, string text, object htmlAttributes)
{
return Html.Label(null, #for, text, htmlAttributes);
}
public static string Label(this HtmlHelper Html, string #for, string text, IDictionary<string, object> htmlAttributes)
{
return Html.Label(null, #for, text, htmlAttributes);
}
public static string Label(this HtmlHelper Html, string id, string #for, string text)
{
return Html.Label(id, #for, text, null);
}
public static string Label(this HtmlHelper Html, string id, string #for, string text, object htmlAttributes)
{
return Html.Label(id, #for, text, new RouteValueDictionary(htmlAttributes));
}
public static string Label(this HtmlHelper Html, string id, string #for, string text, IDictionary<string, object> htmlAttributes)
{
TagBuilder tag = new TagBuilder("label");
tag.MergeAttributes(htmlAttributes);
if (!string.IsNullOrEmpty(id))
tag.MergeAttribute("id", Html.AttributeEncode(id));
tag.MergeAttribute("for", Html.AttributeEncode(#for));
tag.SetInnerText(Html.Encode(text));
return tag.ToString(TagRenderMode.Normal);
}
}
Turn this:
DbCommand command = connection.CreateCommand();
command.CommandText = "SELECT #param";
DbParameter param = command.CreateParameter();
param.ParameterName = "#param";
param.Value = "Hello World";
command.Parameters.Add(param);
... into this:
DbCommand command = connection.CreateCommand("SELECT {0}", "Hello World");
... using this extension method:
using System;
using System.Data.Common;
using System.Globalization;
using System.Reflection;
namespace DbExtensions {
public static class Db {
static readonly Func<DbConnection, DbProviderFactory> getDbProviderFactory;
static readonly Func<DbCommandBuilder, int, string> getParameterName;
static readonly Func<DbCommandBuilder, int, string> getParameterPlaceholder;
static Db() {
getDbProviderFactory = (Func<DbConnection, DbProviderFactory>)Delegate.CreateDelegate(typeof(Func<DbConnection, DbProviderFactory>), typeof(DbConnection).GetProperty("DbProviderFactory", BindingFlags.Instance | BindingFlags.NonPublic).GetGetMethod(true));
getParameterName = (Func<DbCommandBuilder, int, string>)Delegate.CreateDelegate(typeof(Func<DbCommandBuilder, int, string>), typeof(DbCommandBuilder).GetMethod("GetParameterName", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, new Type[] { typeof(Int32) }, null));
getParameterPlaceholder = (Func<DbCommandBuilder, int, string>)Delegate.CreateDelegate(typeof(Func<DbCommandBuilder, int, string>), typeof(DbCommandBuilder).GetMethod("GetParameterPlaceholder", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, new Type[] { typeof(Int32) }, null));
}
public static DbProviderFactory GetProviderFactory(this DbConnection connection) {
return getDbProviderFactory(connection);
}
public static DbCommand CreateCommand(this DbConnection connection, string commandText, params object[] parameters) {
if (connection == null) throw new ArgumentNullException("connection");
return CreateCommandImpl(GetProviderFactory(connection).CreateCommandBuilder(), connection.CreateCommand(), commandText, parameters);
}
private static DbCommand CreateCommandImpl(DbCommandBuilder commandBuilder, DbCommand command, string commandText, params object[] parameters) {
if (commandBuilder == null) throw new ArgumentNullException("commandBuilder");
if (command == null) throw new ArgumentNullException("command");
if (commandText == null) throw new ArgumentNullException("commandText");
if (parameters == null || parameters.Length == 0) {
command.CommandText = commandText;
return command;
}
object[] paramPlaceholders = new object[parameters.Length];
for (int i = 0; i < paramPlaceholders.Length; i++) {
DbParameter dbParam = command.CreateParameter();
dbParam.ParameterName = getParameterName(commandBuilder, i);
dbParam.Value = parameters[i] ?? DBNull.Value;
command.Parameters.Add(dbParam);
paramPlaceholders[i] = getParameterPlaceholder(commandBuilder, i);
}
command.CommandText = String.Format(CultureInfo.InvariantCulture, commandText, paramPlaceholders);
return command;
}
}
}
More ADO.NET extension methods: DbExtensions