What are your favorite extension methods for C#? (codeplex.com/extensionoverflow)
Solution 1
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....
}
Solution 2
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.
Solution 3
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");
..
Solution 4
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!");
Solution 5
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))
{
// ....
}
![beam022](https://i.stack.imgur.com/sVkCd.png?s=256&g=1)
beam022
I'm primarily interested in good software design, patterns, TDD, DDD and Microsoft technologies C#, .net, MSSQL.
Updated on November 19, 2020Comments
-
beam022 over 3 years
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.
-
Jon Skeet over 15 yearsIt's certainly short - but will be unreadable to any new members of your team.
-
mckurt over 15 yearsreadability is the only reason that I wouldn't use this, apart from that its a good idea
-
chakrit over 15 yearsI think readability matters more in the grander scheme of your code than a few shorthand statements that could be quickly looked up/asked.
-
Jon Skeet over 15 yearsPersonally I'd like a separate Formatter object, which the BCL could parse the pattern of once and reuse. That would increase readability and performance. I've asked the BCL team - we'll see...
-
Jon Skeet over 15 yearsI'd suggest renaming "SetTime" to "WithTime" as it's not actually setting it in the existing value. Nice otherwise though.
-
chakrit over 15 yearsThat's nice! You should put it up on Google Code or CodePlex so I can send you some patches :-) I promise it'll be readable :-P
-
cfeduke over 15 yearsI've found myself writing something very similar.
-
cfeduke over 15 yearsI like this too, Jon has it in his, and I use something similar from Umbrella, could stand to drop "ArgumentIs" part.
-
cfeduke over 15 yearsYup, same ToInt64, ToFloat, etc. You can eliminate the if and knock it down to one return if you like.
-
chakrit over 15 yearsWasn't that already done? Since this is just another way to call into the BCL?
-
Jon Skeet over 15 yearschakrit: No - because every time you format, the BCL will have to parse the format string. Format strings usually remain constant throughout the course of a program's lifetime - why parse them more than once each?
-
cfeduke over 15 yearsThis is nice, I remember in my last 1.1 framework writing a series of BetweenInt32, BetweenDateTime, etc.
-
Vyas Bharghava over 15 yearsWhat does this accomplish except for adding one more method call... For me it does not look readable at all.
-
beam022 over 15 yearsIt pops up with a password thing. Just press cancel.
-
Pure.Krome over 15 yearsYeah! this is a kewl extension method too :)
-
chakrit over 15 years@Jon_Skeet I see. That'd add more value to the method as well hehe.
-
chakrit over 15 yearsI don't understand... If you have used string.format before, then you'd certainly can quickly guess that it's a string.format call. And a quick goto definition would tell you that. If you don't like it, just name it 'Format' or whatever you like. Take a look at the '%' format operator in Python.
-
Andrew Bullock over 15 yearsYou should use Decimal for currency else you'll get rounding issues
-
mackenir over 15 years12 fairly basic extension methods. I'm a bit underwhelmed by mono-rocks.
-
mackenir over 15 yearsDateTime.Now.First() - first what? It's only apparent from the sample code.
-
mackenir over 15 years(I'm talking about the released version, not the one you need to use source-control to get)
-
chakrit over 15 years@Rune I did, I just provided this as example. I have my own version of util extensions lib too.
-
chakrit over 15 yearsah ha I used to have a bunch of these as well. But it was kind of too large when you want string.ToInt32 double.ToInt32 float.ToInt32.. blah blah I think I've overused it a bit :-)
-
chakrit over 15 yearsYou could do that in 2 linq select-where statements. Does that count as BCL?
-
cfeduke over 15 yearsYes. (Obligatory comment character limit here.)
-
beam022 over 15 yearsVery nice. But agree that the names could be a lot better.
-
Jon Skeet over 15 years@bovium: You can already see the code. Follow the link in the first sentence - full source is there.
-
Steve Hiner over 15 yearsI love this one but I'm trying to decide if it's right to make the bounds check inclusive on the min value but exclusive on the max value. I wonder if that would be confusing. 5.Between(5,10) is true but 5.Between(1,5) is false. Not even sure that a companion Within method would help. Thougts?
-
Alan over 15 yearsHm, what exactly was wrong with this one? I don't mind the downvote, but I'd honestly like to know if it's not supposed to work or something.
-
Joel Mueller over 15 yearsOn the IsNullOrEmpty one I'd hate to call it on a million-item enumerator. It would loop through all million items just to tell me it's not empty. Better: return iEnumerable == null || !iEnumerable.Any();
-
Pure.Krome over 15 yearsOh dude - awesomesauce! i never knew that! cheers heaps dude. (my post above, edited.)
-
Joel Mueller over 15 yearsGlad you like it. One thing - Any() returns a boolean, so <= 0 probably won't compile. If the enumerable is empty, Any() will return false. This font makes it hard to see, but my original example has an exclamation point in front of the call to Any.
-
Damir Zekić over 15 yearsYou cannot call it "Format" or else it won't compile. I name it "Inject" when I use similar extension
-
hangy over 15 yearsThis should also work as an extension method for IDataReader.
-
beam022 over 15 years@Jon Skeet. Can I use the code and put it in the Codeplex project?
-
beam022 over 15 yearsThis is not using Extension Methods. Its just a static class.
-
Jon Skeet over 15 years@bovium: I'd rather do it myself, putting it on code.google.com and manage the project myself, if you don't mind. Obviously you're within the licence to put it on Codeplex if you keep the appropriate attribution, but I'd rather sort it out myself soon unless you're desperate :)
-
beam022 over 15 years@Jon Skeet. Its put under the MIT license free of use for everybody. Commercially or open source. Why not join forces and make an extension methods library for the public.
-
beam022 over 15 years@Pure.Krome Can I use the code in the codeplex project. And do you not want to become a contributer to that project?
-
Timothy Khouri over 15 yearsRename "F" to "FormatWith" and it'll be better. The functionality is good, but the name needs to be fixed.
-
user1709101 over 15 yearsAnyone can use it - Help yourself
-
Armstrongest over 15 yearsTo make that an extension method change: static public bool CompareFiles(string path1, string path2) to static public bool IsSameFileAs(this string path1, string path2); then use like: if (file1.IsSameFileAs(file2)
-
Pure.Krome over 15 yearsPersonally, i'm not a fan of code that does try / catch to determine the outcome. Try / catch should be used for errors that occur outside of the intended logic, IMO. hmmmmm
-
chakrit over 15 years@bovium sure... @Atomiton I think.. but I don't know Ruby well enough to be sure.
-
chakrit over 15 yearsThis enum-parsing scenario comes up all the time... gotta put this in my lib :-)
-
Joel Mueller over 15 yearsActually, make the "this" parameter of type IDataRecord for maximum compatibility. In my version of this, I have an overload that takes an ordinal, which the fieldName version calls. Saves the "GetOrdinal" followed by a lookup by name.
-
TWith2Sugars over 15 yearsPablo Marambio - any alterative ways I could perform this?
-
TWith2Sugars over 15 yearsIf I remeber correctly convert.ToIt32 could throw an exception
-
ethan over 15 yearsalso a duplicate of stackoverflow.com/questions/271398/…
-
TheSoftwareJedi over 15 yearsIf I didn't want you to use the code, I wouldn't have posted it! :)
-
Judah Gabriel Himango over 15 years+1 for use of the little-known .NET 4.0 design-by-contract APIs.
-
Judah Gabriel Himango over 15 years+1. I don't know why .NET BCL doesn't have a .ForEach extension for IEnumerable<T>
-
abbot over 15 yearsWow, I've been writing methods to map strings to enums (just started using .NET). Thanks, this will absolutely help!
-
Neil over 15 yearsYou might also consider naming this ToEnum<>(), since it comes after the object.
-
David over 15 yearsConsole.WriteLine already has an overload which formats. Console.WriteLine("{0} {1}", value1, value2)
-
Meydjer Luzzoli over 15 yearsUm, what's with the crazy Substring action though? If you're trying to get rid of the BOM there are much better ways of doing it (such as specifying that it is omitted from the encoding).
-
Rinat Abdullin over 15 yearsProblems with these extensions: * All objects are extended (signature pollution) * boxing/unboxing overhead * not all enums derive from int, there could be byte and long as well
-
Adam Lassek over 15 yearsThanks Rinat, I have actually got this down to a single generic method - see stackoverflow.com/questions/303287
-
sina over 15 yearsUse
dt.ToString("yyy-MM-dd_HH.mm.ss");
directly to avoid creating 2 additional String instances. Since this format doesn't include a time zone component, a UTC time would be better viadt.ToUniversalTime().ToString(...)
. -
Jay Bazuzi over 15 yearsI'd be tempted to call the first one
ToXml()
(likeToString()
) -
Jonathan C Dickinson over 15 yearsOooh, you are going to get a nasty memory leak there. Make sure you have a private Dictionary<Type, XmlSerializer> and cache them in there. The reason for this is because every time you create a serializer .Net loads a new assembly into your appdomain.
-
Jonathan C Dickinson over 15 yearsI put this up somewhere else on SO, but someone shot it down. Has something to do with that it terminates the expression (i.e. does not return IEnumerable<T>).
-
Rasmus Faber over 15 yearsTwo different files on different drives might coincidentally have the same FileIndex. You need to compare VolumeSerialNumber also - but then your example will fail, since VolumeSerialNumbers are different.
-
Rasmus Faber over 15 yearsSee also stackoverflow.com/questions/410705/…
-
Portman over 15 yearsApologies to the OP if he intentionally wrote it this way, but the use of MemoryStreams AND XmlReader/XmlWriter was overkill. The StringReader and StringWriter class are perfect for this operation.
-
Alex Baranosky over 15 yearsI like the name "FormatBy"... it is a little shorter than "FormatWith"
-
chakrit over 15 yearsFileInfo and DirectoryInfo is rather slow compared to their string File and Directory counterpart. You might want to profile those.
-
TWith2Sugars over 15 yearsNot a problem!, I'll use this altered version myself, thanks.
-
TWith2Sugars over 15 yearsJust thinking... would it be worth it if we used the "as" keyword and just returned the result as opposed to casting and and catching an exception?
-
TWith2Sugars over 15 years@Jonathan C Dickinson Thanks for the warning!
-
WestDiscGolf over 15 yearsFor string formatting performance and madness you may want to check out Phil Haack's blog about different ways of doing it ... haacked.com/archive/2009/01/14/named-formats-redux.aspx
-
Dan Nelson over 15 yearsWhat about use an Enum in the parameter instead of plain string
-
MarkJ over 15 yearsIt's an extension method, of course it's going to be unreadable to new members of the team. I thought that was the idea with this witty stuff? How else will the new members know how clever we are?
-
klkitchens over 15 yearsOk... I just went to put this into action and went with .With -- so you get "This is a {0}".With("test") and it's very readable and makes sense. FYI
-
Anton Tykhyy about 15 yearsBetter use TryGetValue, you're doing two lookups instead of just one.
-
JoshBerke about 15 yearsx.ThrowIfNull seems wrong to me. Your calling a method on what appears to be an instance member checking if its null. I know this will work since extension methods are just static methods, Its just not intuitive.
-
flq about 15 yearsIsn't it somewhat dangerous to already enumerate "enumerable" by calling "Count" on it in a contract check? Or is this not a runtime check?
-
Joel Mueller about 15 yearsYou still have to put a variable name in front of every method/property call. Why not just make your original variable name shorter?
-
chakrit about 15 years@Joel Muller it's not always my variable... think Someone.Else.Namespace.With.WeirdClass.Instance
-
Admin about 15 yearsWould be better as this IList<T>
-
fretje about 15 yearsWouldn't the name "IsBetween" make more sense? Also maybe make an IsBetweenInclusive and IsBetweenExclusive. No idea which one to take for default though.
-
Lazy about 15 yearsWhy not return the values using yield return and return "actual lazy" enumerators? Would to certain extent take care of your high-performance code comment.
-
Sensei about 15 yearsBeware, this is not threadsafe. You should definitely synchronize your access to the static serialisers dictionary.
-
TWith2Sugars about 15 years@Yann Schwartz How would I start with that?
-
Neil about 15 yearsPost on why LINQ's IEnumerable<T> extensions don't include a ForEach: stackoverflow.com/questions/317874/…
-
Joel Coehoorn about 15 years@Steve: it makes more sense if it were a datetime extension.
-
jonny almost 15 yearsrequires .NET 3.5, uses delegates to evaluate object graph in try catch stackoverflow.com/questions/298009/…
-
Steve almost 15 yearsI also use the c# 3.0 property initializer syntax wherever possible to achieve the same result.
-
Steve almost 15 years@chakrit, here's an example. It only applies when creating the object Button n = new Button { Name = "Button1", Width = 100, Height = 20, Enabled = true };
-
Alex Baranosky almost 15 yearsTo me between implies: 5.Between(5,10) returns false, and 10.Between(5,10) returns false as well. That just feels natural to me.
-
Pop Catalin almost 15 yearsVery usefull method, but I don't think it should be and extension method.
-
MordechayS almost 15 yearsIf you're writing a text editor it probably warrants an extension method, but I agree most of the time it's probably no more than a static private method
-
Greg over 14 yearsI like, except I wouldn't say Is or As because doing so implies type comparison/conversion. This is really a parsing method.
-
sisve over 14 yearsAdding " ..." would return ShortenToLength + 4 chars, ie a string longer than what the documentation says.
-
Arnis Lapsa over 14 yearsJust use collection initializer =>
var list = new List<int>{5,4,8,4,2};
-
Arnis Lapsa over 14 yearsMade this too. One of the rare things i miss from Visual Foxpro. :)
-
Arnis Lapsa over 14 yearsFinally something unseen. I like it. :)
-
Arnis Lapsa over 14 yearsCheck out MvcContrib.FluentHtml
-
andleer over 14 yearsYou could go with ParseIsInt32(), ParseToInt32 and ParseAsInt32()
-
cbp over 14 yearsGood points, Rinat. I wish there was a way to write these extension methods.
-
Frank Krueger over 14 years@Yann, @T, It's much easier if you just add the "thread static" attribute. Then a new cache will be created per thread. No need for synchronization.
-
Dan Diplo over 14 yearsNote that Enum.TryParse<T> has been added to Net 4.0 - blogs.msdn.com/bclteam
-
Dan Diplo over 14 yearsWould this be better? public static bool IsNull<T>(this T obj) where T : class { return (obj == null); }
-
marijne over 14 yearsShouldn't you be closing those file handles?
-
Ryu over 14 yearsThis code doesn't compile. Array's don't have Contains method
-
Ryu over 14 yearsWell it compiles if you're using System.Linq;
-
Thomas Levesque over 14 yearsThe Aggregate in Capitalize is pretty bad for performance, because it creates many string instances. Why not use word.Substring(1) instead ?
-
Thomas Levesque over 14 yearsNo example ? It's pretty straightforward, but maybe not for everyone
-
Christian.K over 14 yearsYou should at least change that "catch" clause to only catch those exceptions that ChangeType() will raise when it cannot "convert" the reference. I think you wouldn't want to have any OutOfMemoryException, ExecutionEngineException, ThreadAbortException, or alike being treated as a conversion error. Those things will otherwise be pretty hard to track errors.
-
P Daddy over 14 yearsIt would be more .NETy if you used
IComparer<T>
orComparison<T>
(or an overload for each), instead of a "less" function, which smacks of STL. -
RCIX over 14 yearsAs i understand it a Comparison<T> is basically a Func<T,T,int> in disguise, where i need a bool to work with the insertion sort.
-
P Daddy over 14 yearsYes,
Comparison<T>
is equivalent toFunc<T, T, int>
, which is the same interface asIComparer<T>.Compare
. This is the standard comparer interface that .NET developers are used to. Most sorting functions only need to compare less than or greater than. You've chosen less than. If you look in Reflector atArray.SorterGenericArray.QuickSort()
(orArray.SorterObjectArray.QuickSort()
), you'll see thatArray.Sort
also only uses less than, but it does it withcomparer.Compare(a, b) < 0
, keeping with the established interface for the platform. -
P Daddy over 14 yearsAccepting
IComparer<T>
also allows your users (or you) to useComparer<T>.Default
instead of implementing the comparison by hand. The best interface when a comparison is involved usually has three overloads, one takingIComparer<T>
, one takingComparison<T>
, and one taking no comparer and assumingComparer<T>.Default
. -
Tommy Carlier over 14 yearsIf you use the ArgumentNullException-constructor with only 1 string-argument, that argument has to be just the parameter name, and not the error message. So your code should look like this: if (obj == null) throw new ArgumentNullException(parameterName);
-
David Miani over 14 yearsIt seems to me that multiple people have different ideas as to what is natural. Because of this it probably should be explicitly stated what is being used (ie Inclusive vs Exclusive), as this could be a very easy source of errors.
-
darkAsPitch over 14 yearsthis mimicks pythons random.choice(seq) function. nice.
-
andriy over 14 yearsDateTime.Now.First will be clear enough in Intellisense if the method is well-documented.
-
ICR over 14 yearsYour IsNullOrTrimEmpty helper is in .NET 4.0 in the form of string.IsEmptyOrWhiteSpace
-
ICR over 14 yearsThe BCL guys, but yes, hi 5 indeed.
-
moomi over 14 yearsUse as you will for CodePlex or lining your bird cage.
-
jpbochi over 14 yearsI recommend reading this before using method: blogs.msdn.com/ericlippert/archive/2009/05/18/…
-
jpbochi over 14 yearsCan someone be kind enough to explain it to the less gifted of us?
-
jpbochi over 14 yearsYou can substitute all the code in this function for one line:
return string.Join(separator, list.ToArray());
-
jpbochi over 14 yearsBeware that argument validation should not reside in the same method as the
yield return
's. The problem is that theArgumentNullException
's will be thrown at the start of iteration of the returned "query". It should have been thrown at the call to theZip
method. -
jpbochi over 14 years+1 I particularly liked the Pipe method. I had to download your source to find out that it was like a
Where
on a single value, though. Could someone edit the answer to make this point clearer? -
jpbochi over 14 yearsI would rather use
as T
instead of casting -
jpbochi over 14 years@Dan Diplo I don't think your change would make any difference at all. It make no difference to use generics to compare an object to null.
-
Kaveh Shahbazian over 14 years'Pipe' is different than 'Where'. 'Where' is a 'map' (in mathematical sense and in functional languages) which takes a set (collection & in .NET case an IEnumerable<T>) & a function (which in .NET land is a delegate and can be represented by a lambda expression like x => x > 2; the only restriction on provided predicate is that it must return a Boolean. 'Pipe' operator is a common tool in functional languages. It's main usage is for chaining computations (function calls). It gets a value & a function (like x => f(x)); then it applies the function to the value & returns the result.
-
Tom Bushell over 14 yearsMaybe "EqualsAnyOf" would be a better name than "In"?
-
Winston Smith over 14 yearsI'm not sure I like it - I like the brevity of
In
, but maybeIsIn
would be better. -
Ian over 14 yearsI'm afraid some of these I don't like. 500.Sleep() for example... Just a little too cryptic for my liking. I don't see what's wrong with plain Thread.Sleep()
-
Ray Burns over 14 yearsThe advantage of using generics is this: If you try to call Dan Diplo's generic version of IsNull() on a struct you get a compile-time error. If you call John Kraft's original version it doesn't warn you (and also adds boxing code).
-
John Kraft over 14 years@Ray Burns You are absolutely correct, however, I consider that to be a plus on mine; it won't throw an exception, and the boxing is the preferred behavior in the code that I am writing. Besides, in the current environment I work in (CRUD line-of-business apps), we never have a need for structs; so it doesn't matter.
-
Max Toro over 14 yearsUsing the same Contains method: (new[] { 1, 2, 3 }).Contains(a)
-
Thomas Levesque over 14 yearsI think it could be a good idea, but it's hard to implement... You can easily check whether x is null, but if you want to perform the check for every level of the "path" (SomeProperty, MaybeAMethod), it gets really hard. I tried to do it by rewriting the expression tree, but I eventually gave up...
-
Joel Mueller over 14 yearsI called my version of this
ToDelimitedString
to avoid confusion with the built-in LINQ Join method. -
Joel Mueller over 14 yearsLooks a lot like System.Data.DataSetExtensions.dll that comes with .NET 3.5, except not as efficient.
-
Dan Tao over 14 yearsIf your intention is for this method to be used within LINQ queries, then you might want to consider implementing a
ShuffledEnumerable
class that only does this work (and probably caches it) onGetEnumerator
to provide lazy evaluation a.k.a. deferred execution. Otherwise if someone calls, e.g.,var shuffledNames = myObjects.Select(x => x.Name).Distinct().Shuffle();
the operation will get executed immediately, which may not be what he/she expects. Good answer, though! -
Rauhotz over 14 yearsWhy not just calling List<T>.AddRange(IEnumerable<T> collection) within your method?
-
Dan Tao over 14 yearsCouple things: I'd recommend that
OneOf
should accept anyIList<T>
. Then you could always also have an overload that takes aparams
arg and just passes that into theIList<T>
overload. I gave an answer (way down at the bottom right now) with aNextBool
method similar to yourCoinToss
, but with an overload that takes aprobability
parameter (what if I want something to happen 75% of the time?). Also, just a nit pick: your example code will throw aNullReferenceException
sincerand
is never initialized. -
Dan Tao over 14 years@Will: Actually, it would be best to accept an
ICollection<T>
; then it could also be used on, for example,LinkedList<T>
andHashSet<T>
, not just indexed collections. -
Dan Tao over 14 yearsI believe
ToOrNull
has the exact same behavior asToOrDefault
(i.e., if you callToOrDefault
on a reference type with an unsuccessful conversion, it will returnnull
). But more importantly, it seems kind of redundant to me sincevar s = myObject as string
accomplishes the same thing asvar s = myObject.ToOrNull<string>()
-- but without potentially having to catch anInvalidCastException
. Am I missing something? -
jpbochi over 14 years@Dan: This is a great point. There's an elegant way to use deferred execution without an explicit declared class, though.
yield return
solves the problem. I'll edit my answer. -
Dan Tao over 14 yearsSolid. Now it's basically the logical opposite of
OrderBy
. Nicely done! -
Aran Mulholland about 14 years@Arnis L this lets you ADD items to an already existing List<T> and can be called multiple times.
-
John Leidegren about 14 yearsIf you wanna do that with enumerations change the type
object
to justEnum
. -
John about 14 yearsVery nice, could be expanded to first check Query string, then check ViewData, then check SessionState, finally return default value.
-
Joel Coehoorn about 14 yearsI'd use
default(T)
for this and remove the class requirement. -
Joel Coehoorn about 14 yearsI'd rename this to
AppendRange()
- it makes the difference between this and a collection initializer more obvious. -
Joel Coehoorn about 14 yearsIt's still dangerous because some enumerables can only be iterated once, but I fixed it so that at least it stops after two iterations rather than determining the entire count.
-
Joel Coehoorn about 14 yearsI'd rename these to
Append()
(and use iterator blocks as suggested by peSHlr) -
Anthony about 14 yearsJoel, peSHIr: good suggestions, I have updated the answer to do this.
-
adrianm about 14 yearswouldn't ´builder.AppendFormat(format, args); builder.AppendLine();´ be more in the spirit of the stringbuilder (i.e. no temporary string)
-
MordechayS about 14 years@adrianm isn't that 1 extra string though (albeit just a \n)?
-
adrianm about 14 yearsAppendLine uses a static "\r\n" string. string.Format creates a new string every time which need to be GC:d.
-
stevehipwell about 14 yearsWhy are you looping the values when you can call
list.AddRange(values);
? -
stevehipwell about 14 yearsAll of these methods appear to be un-needed as you can use the
as
keyword to get a value from a reader allowing for null. If you combine the null coalescing??
operator with the as operator you can even have a non-null default value for going directly to a value type. See stackoverflow.com/questions/746767/… -
stephbu about 14 yearsThis seems a a little flawed in assuming FQDN structure - try these test cases. www.msn.co.uk vs. www.msn.com vs. msn.co.uk co definitely isn't the root domain for msn.co.uk.
-
Adam Lassek about 14 years@Stevo No, you can't use
as
in this way. Did you test this? DBNull values will throw an exception. -
stevehipwell about 14 years@Adam Lassek - Actually yes I have tested this and have it running in a production environment. I have no idea where you got the impression that an exception would be thrown if a value is DBNull, it really wont; that is data access 101.
-
BlueRaja - Danny Pflughoeft about 14 yearsEdited to allow covariance in pre-.net 4.0
-
JP. about 14 yearsJon, your site says that this is "licensed under the Apache licence...". Which license is correct: MIT/Apache? Thanks
-
Joel Coehoorn about 14 yearsThere's a separate keys collection property in the dictionary that might be able to do this faster
-
Ken about 14 yearsPython and Common Lisp both use inclusive on the low end, and exclusive on the high end, as in the code above. Yes, it seems "unnatural" at first, but in the first 5 minutes it becomes tremendously useful -- I would classify it as a miswart. After all, every single character in the above code (except possibly
<
) seemed "unnatural" to me, at first, too -- writingpublic static class ComparableExtensions {
before my code doesn't exactly seem intuitive. -
johnc about 14 yearsSurely if it is null, the call will fail (I once tried to implement an IsNullOrEmpty method on a string and felt foolish when I realised), but it would work well for value types
-
Jim Schubert about 14 yearsA much faster way to get a delimited string is
string.Join(",", strings);
wherestrings
is an array. This generates roughly 1/3 the IL as the StringBuilder method. -
Daniel about 14 yearsNullable tpyes have a HasValue property built into them.
-
John Leidegren about 14 years@Jim Schubert: Can you back that up with some benchmarks? The size of the IL isn't a good measurement of speed. Fewer instructions doesn't automatically imply faster running times.
-
cbp about 14 yearsJust point out that this is still a useful method to have for StringBuilder. If you wanted to seperate the calls to the joining method with other code, then you would have multiple calls to string.Join anyway which would negate any performance benefit over using a StringBuilder.
-
Kamarey about 14 yearsAnd what purpose of all these? Why not just write, say, "item as Type" instead of "item.As<Type>()" as you do?
-
Jim Schubert about 14 years@John: Benchmarks have been done on these thousands of times, and they rarely, if ever, show any perceptible performance difference. I'd like to do benchmarks on this to see the difference, and compare string.Join/Format/Concat, StringBuilder.Append/AppendFormat, and + operator concatenation. A 300ms difference in building a string can easily be offset by network and database performance, though.
-
johnc about 14 years@Kamarey It is a subjective preference, but it reduces confusing parens that can build up when you have multiple casts. item as Type becomes (item as Type) or ((Type)item) if you need to use item as the cast type. Also, the left to right scanning of item.As<Type>(). ... is much more readable over boxing in some confusing cases. I did say it was simple, and I agree it is subjective, but I find it can be quite powerful in code readability.
-
John about 14 yearsI made a similar method but I also added an overload which takes BetweenType enum to specify how the compare should take place. sometimes you want a true between (exclusive) sometimes inclusive and sometimes to include one or the other bounds.
-
John about 14 yearsI have a similar method called Parse<T> that I use for all sorts of types, not just int32
-
Iain Galloway almost 14 yearsDoesn't String already implement IEnumerable<char>? So you'd just need to do return new String(input.Reverse());
-
Lazy almost 14 yearsToPluralString() is just plain simplistic. English is not my native language so it seems silly to me, but it does not even work very well in English in general. ;-)
-
Joe White almost 14 yearsDelphi avoids the confusion of "between" by calling their function "InRange", and returning true at the endpoints. I find this is a more helpful name than the ambiguous "between".
-
Omar almost 14 years@Simon - Fixed the documentation. @peSHIr - I edited it, could you elaborate please.
-
Gabe almost 14 yearsThis would be useful for when you have a lot of events to hook up, because C#'s property initializer syntax doesn't support events.
-
Pure.Krome almost 14 years@peSHIr : care to give an example? basically, for a large number (lets keep this simplistic and say 'the majority') of 'things' that are either 0 or 2+ .. end with an s to define that they are plural (or none for 0). eg. cat/cats. dog/dogs. friend/friends. bug/bugs. Now, this won't work for things like fairy/fairies (and all other words that end in
y
) or tooth/teeth .. etc. So it's a helper ... but not the be-all-end-all of a singlular-to-plural modifications. -
Lazy almost 14 years@Pure.Krome: You already give examples yourself. ;-) Some more: index/indices, saldo/saldi and other Latin based ones. If this is just a helper for use in ToReadableTime() - where it would work great, even if that is not globalized in any way, but the function is not used (?) - I would have expected ToPluralString() to be private instead of public.
-
KdgDev almost 14 yearsVisual Studio error: Error 2 'System.Array' does not contain a definition for 'Contains' and no extension method 'Contains' accepting a first argument of type 'System.Array' could be found (are you missing a using directive or an assembly reference?)
-
KdgDev almost 14 yearsProblem: this requires than 1 parameter. In which case, best to just use the LINQ contains method, right?
-
KdgDev almost 14 yearsWon't compile, problem with the S and T.
-
Greg D almost 14 yearsI don't really like this one. The where is already performing the if, that's the whole point of the predicate.
-
Casebash almost 14 yearsThis should be a separate question
-
brickner almost 14 yearsHow about using IEnumerable instead of ICollection and Any() instead of Count?
-
Tadas Šukys almost 14 years@brickner IEnumerable<T>.Any() - only generic IEnumerable<T> has Any().
-
Brady Moritz almost 14 years@Steve, Im thinking this is provider-dependent.. Ive had oracle providers blow up on DBNull balues, but some others didnt. Been too long though, I'm probably wrong ;)
-
Brady Moritz almost 14 yearsI recommend seeing if can do this for strongly typed datatables? they also dont allow nullable types, and are a huge pain to work with. In fact they are much worse, because if you try to access a field that has a null, the access itself throws an exception.. it doenst even return a dbnull you can inspect.
-
Brady Moritz almost 14 yearsthis is also userful outside of property initializers, because you can only use them when creating a new object. this extension can work on previously created objects.
-
andleer almost 14 yearsPart of the idea here is that some conditionals won't execute on SQL with an IQueryable so you have to separate them.
-
NickAldwin almost 14 yearsAnd the reverse is already included with .NET as a built-in extension method (yeah, that sounds weird, built-in extension method): stackoverflow.com/questions/208532/…
-
BenAlabaster almost 14 yearsI'd probably just add an overload with a third param to make it more readable and provide a companion enum Match.Inclusive, Match.Exclusive. Default the third param to make it inclusive, but the overload allows that to be explicitly specified: 5.Between(1, 5); returns true, but 5.Between(1, 5, Match.Exclusive); returns false.
-
JBRWilkinson almost 14 yearsWhoah, Pokemon exception handling is gonna hide issues like ThreadAbortException, etc. Please catch something specific.
-
BuddyJoe almost 14 yearsI would probably write two extension methods - IsInOne() and IsInAll()
-
torial almost 14 yearsThat reminds me of the Python PEP 313, which was an April Fools joke to include Roman Numeral literals in python: python.org/dev/peps/pep-0313
-
Thomas Levesque almost 14 yearsWow, 8 parameters (not counting the
this
parameter) ! IMHO, any method with more than 4 parameters needs refactoring... -
Thomas Levesque almost 14 yearsI eventually managed to make it work: tomlev2.wordpress.com/2010/02/21/…
-
Thomas Levesque almost 14 years@johnc, no the call will not fail if o is null. Extension methods are actually static methods, not instance methods. And the IsNullOrEmpty extension method works fine for me...
-
Thomas Levesque almost 14 yearsYou forgot TrueFalseFileNotFound :P
-
Thomas Levesque almost 14 yearsIf you need case insensitive keys, you can pass StringComparer.InvariantIgnoreCase to the dictionary constructor
-
si618 almost 14 years@Thomas - Even better! Assumes you have access to the ctor, but definitely the best approach.
-
EightyOne Unite almost 14 yearsnice. Just what I'm looking for :-)
-
Fredy Treboux almost 14 yearsHey, that's great!. I actually gave it a try a couple of days ago and came up with this: bit.ly/9777Y0 but your approach seems much cleaner. I agree with your conclusions though.
-
StriplingWarrior almost 14 years@Joel: Non-default values for native types are legitimate arguments more often than null values. Checking against null makes more sense to me than checking against default. Of course, I just generalize the whole idea by saying
Require.ThatArgument(input != null)
orRequire.ThatArgument(personId > 0)
. It doesn't take that much more code, it's a lot more flexible, and it reads nicely. I have additional overrides that take funcs for when you want to customize the error message or the exception itself. -
StriplingWarrior almost 14 yearsI don't have to add a bunch of hard-coded values to a list nearly as often as I need to append values to an IEnumerable generally. When I need to do something like this, I just say
items = items.Concat(new[] {5, 4, 8, 4, 2})
. It works with any IEnumerable (for both the subject and the argument), and if you really want to end up with a list, just callToList()
when you're done. -
slolife almost 14 years@Jonathan C Dickinson: It appears from the MSDN docs here msdn.microsoft.com/en-us/library/… that the constructor that is used (new XmlSerializer(type)) does not have a memory leak problem. So maybe the caching code isn't needed?
-
Mark Hurd almost 14 yearsThis probably should be duplicated with Literal instead.
-
Greg D almost 14 yearsI've written basically identical code myself on more than one occasion.
-
fre0n almost 14 yearsInteresting. But not exactly extension methods.
-
Lasse Espeholt over 13 years
19.June(1976)
is fine (testing at least) but I don't like30.Minutes()
. Why not use operator overloading to reach something more equivalent to scientific notations like30 * min
or30 * Minutes
if you like. -
Jon Skeet over 13 years@lasseespeholt: Well, in both cases you'd have to have
min
andMinutes
defined somewhere in each source file that uses them... and that could get annoying. With the extension method it's just a case of adding theusing
directive (which we don't tend to look at anyway). But it's definitely a matter of taste. -
Lasse Espeholt over 13 years+1 I really like this, but I prefer
CoinToss
to be implemented withrng.NextDouble() < .5
because internally.Next(int)
is made with.NextDouble()
so you would save a cast, a * and a check. -
Lasse Espeholt over 13 years@Jon Ahh good point ;) of cause it could be static so you could do something like
30 * SI.min
but that just make it less clear. -
Thomas Levesque over 13 yearsVery similar in purpose to the method I posted here. Your implementation allows more flexible patterns, but mine is probably faster ;)
-
Thomas Levesque over 13 yearsWhat if I want
thingy.NullOr(t => t.Count)
, whereCount
is an int ? You should returndefault(TReturn)
rather than null, that way you won't need theclass
constraint and it will work for value types too -
Esben von Buchwald over 13 yearsTIn should be required to be a class, otherwise this entire extension method makes no sense (value types cannot be null). And your example with t.Count does work with the above extension method. Could you take a second look?
-
Esben von Buchwald over 13 years@Kamarey some people call this "fluent" programming - always programming left to right, never having to back up to put parens on things. Reaching for the arrow keys slows things down. It also keeps in style well with Enumerable and Observable operators. @johnc I would add a
To<T>
to the list that does(T)item
. -
Jim Schubert over 13 years@Scott: this is a useful method to a common problem. However, I believe
TReturn elseValue = default(TReturn)
is only available to .NET 4.0? I have 3.5 SP1 and I've never seen that construct (neither has my compiler). I just moved this to inside the method. One issue, however, is that boxing a nullable type to object for use with the method yields an unexpected result (0 vs expected null). -
Esben von Buchwald over 13 years@Jim: the
default(T)
keyword has been there since VS2005, but I think default parameters is a new .NET 4 feature. The easy way around it should be to have two variants, one that takes the param and one that does not. I'll update the answer to be CLR 2.0 compatible. Regarding the boxing - that's the point ofdefault
. It will be 0-initialized data for a value type, and null for all reference types. A TReturn of a value type should remain unboxed all the way through the function. -
Jim Schubert over 13 years@Scott: My question was about the default parameter, which I've only seen in dynamic languages like Ruby. My point regarding nullable types is that returning
x.Value
should return null (if, for example,int?
was null) or the value ifint?
has a value. Returning0
whenint? x = null
is passed and boxed to object is an odd case. I've seen similar checks for nullable types in libraries such as fluent nhibernate and linfu (I think) for this specific case, allowing you to drop the class constraint as previously suggested. -
Esben von Buchwald over 13 years@Jim I believe the default param like that is also possible in C++. I don't know why it would only be common in a dynamic language, because it is a statically typed feature (template params are known at compile time). Regarding
int?
, the class constraint is required or the function won't compile. You cannot compare tonull
without requiring a reference type. Now, it is possible to have a second version of the function that takesTIn?
But what should it do? Return a null or the boxedValue
? But we already have that in the form of the nullable.. I don't see the added value... -
Jim Schubert over 13 years@Scott: Thanks for mentioning the default parameters in C++. I have seen them in C++, but that was in school and I had long since forgotten about them. In Ruby, they're called "optional parameters" instead of "default parameters" and I associated them with dynamic languages because they force the type of the parameter. In Ruby's case, the variable's type can't be changed but the variable can be reassigned. I have heard about default parameters in VB.NET under 3.5 and it's enough for me to upgrade to 4.0. You're right, though, about there being little added value for nullables.
-
Jim Schubert over 13 years... I just thought the side effects of boxing a struct were worth mentioning.
-
Esben von Buchwald over 13 yearsAs mentioned, this is for WinForms only. It may work with WPF but there are issues (described in the comment about WPF at msdn.microsoft.com/en-us/library/…). The best solution for WPF I've found is described in geekswithblogs.net/lbugnion/archive/2009/09/05/… (though, as it's a static property, it does not really work as an extension method.)
-
CodesInChaos over 13 yearsBe careful when using it with float or double. The semantics of those differ between IComparer and the < = > operators for infinities and NaNs. That 0 is signed (there are distinct +0 and -0) might create problems too.
-
CodesInChaos over 13 yearsI don't think this method should use Trim. Trimming the input should be the responsibility of the caller.
-
CodesInChaos over 13 yearsAn implementation using StringBuilder should be faster.
-
Jürgen Steinblock over 13 yearsCould be extende to be more generic, too
public static bool CompareByProperty<Tself, Tother>(this Tself self, Tother other, string propertyName)
but you will have to change the comparison to useEquals(value1, value2)
instead of==
since == compares the reference for object types: stackoverflow.com/questions/814878/… -
Simen Echholt over 13 years((src == null || src.Count == 0) ? true : false) == (src == null || src.Count == 0)
-
jpbochi over 13 yearsWhy not an
IsNullOrEmpty<T>()
that accepts anIEnumerable<T>
? -
jpbochi over 13 yearsBy the way, you lost my vote up by appending that
? true : false
. -
Greg over 13 yearsThis should be split into two separate answers. The first one is ok (should be IEnumerable<T> instead of List<T>). The second is dubious. I agree with @SchlaWiener, make it generic. I'd also lose the
catch
. If an exception is thrown, let the caller decide how to handle it. -
Michael Stum over 13 years@CodeInChaos The Benchmarking in stackoverflow.com/questions/228038 measured that StringBuilder is slower.
-
Esben von Buchwald over 13 yearsThe Reactive Extensions includes IEnumerable<T>.Run() with many overloads. Apparently Erik Meijer's group is at odds with Eric Lippert's group.
-
Davy8 over 13 yearsNot sure what I think of using @this as the parameter name. On the one hand since it's an extension method you can think of it as a regular class method. On the otherhand, using a (common) keyword as a parameter name rubs me the wrong way. Sounds interesting though.
-
CodesInChaos over 13 yearsYou're right. It seems like the thread safety requirements (probably to ensure immutability of the string returned by ToString) slow StringBuilder down a lot.
-
Esben von Buchwald over 13 yearsI originally picked up @this somewhere on a blog or maybe here on SO. Initially I had the same misgivings, but I've been using it for all my extension methods for the past few weeks and have grown to really like it. I think the "can think of it as a regular class method" outweighs pretty strongly the concern about reusing a keyword. I did think about using "th" or "self" for names, but I especially like how the @ really jumps out. It constantly reminds me what kind of method I'm in.
-
xofz over 13 yearsHey Scott, I don't really have much experience with Tasks or Rx and I'm having a hard time following the implementation of this method. Is this useful for when evaluating individual items in a sequence is expensive (thus warranting async eval)? Does it create a new thread for each item or does it reuse the same job thread as more items are pushed?
-
Esben von Buchwald over 13 yearsThis is useful for when the sequence is expensive. A single thread is pulled from the pool to walk the enumerable asynchronously. It does not return until the enumerable is completed or an exception is thrown. Technically, none of the dispatcher stuff is necessary for this example.. I included it because I write a lot of WPF code and this is a frequent pattern of mine: send a task go do something, publish it as an observable, dispatching the results through the UI thread's message queue.
-
dalle over 13 yearsHope you don't encounter any surrogates or combining characters.
-
binarydreams over 13 yearsAny reason why
enumerable.ToObservable(Scheduler.TaskPool)
doesn't solve the same problem? -
Esben von Buchwald over 13 years@Richard - nope! Didn't know about that function. :)
-
Thomas Levesque over 13 yearsThe IsNullOrEmpty method is a good idea, I use it all the time (but with IEnumerable<T>, not List<T>)... but I'm pretty sure it has already been posted. Regarding the second method, I see no reason to restrict it to FileInfo. Also, passing a string with the property name is a bad idea: you can do the same with a delegate, and you avoid the overhead of reflection
-
Can Sahin over 13 yearsSo, what's wrong with simply writing
{ var x = someVeryVeryLonggggVariableName; /* do something with x */ }
? -
Thomas Levesque over 13 yearsThere is an issue with this solution: you can only use it if the event is declared in the current class, not if it's declared in a base class...
-
Will Vousden over 13 years@Thomas: Isn't the same is true for raising events manually? The solution is to use the
protected virtual void OnBar(Eventargs e)
pattern outlined here: msdn.microsoft.com/en-us/library/hy3sefw3%28VS.80%29.aspx. -
Thomas Levesque over 13 yearsYes, but what I mean is that your solution doesn't work in the general case
-
Greg over 13 yearsGeneralized to ICollection<T>
-
SLaks over 13 yearsActually, this is thread-safe in older versions too. I've written identical methods myself.
-
chakrit over 13 years@Heinzi You get a new scope (the With block scope) and the ability to inline complex access to the object. Also, it doesn't interrupts your train of thoughts as much since you don't have to backtrack and put it in a variable. See: msdn.microsoft.com/en-us/library/ms172864(VS.80).aspx ...
-
Agent_9191 over 13 yearsHow is this an advantage over the default OrderBy and OrderByDescending?
-
KeithS over 13 yearsOrderBy() cannot be chained; each call to OrderBy() sorts by a single projection of the collected type. You could still make it work if the sorting algorithm used were stable like MergeSort, but the built-in sorting helper is an unstable QuickSort, so there's no guarantee of maintaining relative order when sorting by equal terms. Chaining OrderBy() would also run an O(nlogn) function once for each OrderBy(); this set of methods sorts once no matter how many terms you compare.
-
abatishchev over 13 years@jpbochi: This is just Microsoft demagogy
-
Esben von Buchwald over 13 yearsThis could be improved by avoiding the ToArray(). While OrderBy cannot be chained, you should be able to chain all of the
Comparers
into anIComparer<T>
that you pass to a single OrderBy, right? -
KeithS over 13 yearsWell, sorting (ANY algorithm) requires knowledge of the entire Enumerable, because the very last element could be the one that comes first in the ordered collection. OrderBy(), behind the scenes, basically does what I'm doing here; slurp the source Enumerable into a finite collection, sort it, then yield through it.
-
Esben von Buchwald over 13 yearsPoint taken. :) Also: how does this set of classes differ from the Enumerable.ThenBy() and IOrderedEnumerable types in the .NET Framework?
-
KeithS over 13 yearsActually, it doesn't as written. I didn't know about the existence of ThenBy() when I first wrote this. However, there are some advantages. Because it's a roll-your-own, it's more extensible; for instance, you could add OrderUsing() and ThenUsing() methods that allow passing a Comparison instead of just a projection (allowing sorting based on members that aren't IComparable). You can also performance-tune the sorting by replacing Array.Sort with, for example, a parallel MergeSort.
-
John over 13 yearsThanks Jim. Keep up the constructive comments, very useful.
-
KeithS over 13 yearsWe have some similar ones in our codebase: IsBefore(), IsOnOrBefore(), IsOnOrAfter(), IsAfter(), IsBeforeToday(), IsAfterToday(). They wrap rather trivial code, but they improve readability significantly.
-
Jim Schubert over 13 years@John: no problem. Here's a few issues: You're generating a private class with public accessors. StringBuilder has an
AppendFormat
method which uses index formatters just likeString.Format
. You shouldn't be calling Replace on String template place holders like that anyway. You're implicit-typing string. The only reason to convert astruct.Name
to the alias is readability, even then it doesn't make much sense. And,IntPtr
is platform-specfic so this code only works on 64-bit. The code generated by this won't reflect the actual code you're trying to generate. -
Jim Schubert over 13 yearsAlso, I apologize for the laconic answer-- I was at work. Here is an excellent chapter from O'Reilly on reflection which I think will help you to better examine the types you're trying to mimic the code for: oreilly.com/catalog/progcsharp/chapter/ch18.html
-
John over 13 yearsShould a private class not have any accessors with more visibility than private? I would rather force the programmer to change the visibility than than to assume public or anything else. I realize there is the appendformat and I use it quite often but I also need the new line and unfortunately we don't have and AppendFormatLine.
-
John over 13 yearsGenerally I think you are missing the point entirely. This is not intended to be used as is. More likely it is to be used on a more customized basis. For example, you have a large object you want to represent, either from a DB or a class you don't have access to the source. You run through linqpad to generate the class, make few mods and off you go.
-
John over 13 yearsBTW: It is my opinion that if you don't have enough time to extrapolate on your negative opinion you should keep it to yourself until such time that you do. Thanks again - John
-
Jim Schubert over 13 years
Should a private class not have any accessors with more visibility than private?
No. Unless this class is a nested class, which your code doesn't suggest, you'll get the errorElements defined in a namespace cannot be explicitly declared as private, protected, or protected internal
. I can understand quickly generating classes to match db, I do it myself. Also, StringBuilder hasAppendFormat()
andAppendLine();
Just call them both or write an extension method called AppendFormatLine. -
John over 13 years"No. Unless this class is a nested class, which your code doesn't suggest". My code doesn't suggest a thing. It simply generates a class and forces the programmer to decide what the accessibility of the generated class should be. "StringBuilder has AppendFormat() and AppendLine(); Just call them both or write an extension method" That is one way to solve it. I could also use string.Format inside the AppendLine.
-
John over 13 years"You're implicit-typing string. The only reason to convert a struct.Name to the alias is readability, even then it doesn't make much sense". Please explain this further. Are you saying I should leave it as "String", as it comes through, instead of "string"? "And, IntPtr is platform-specfic so this code only works on 64-bit". All well and good but the code will work in 32 bit. I'm not using IntPtr anywhere. I'm simply representing it as a long if it comes through. As is the case in the example I provided.
-
Jim Schubert over 13 yearsImplicity-typing string using the
var
keyword causes the compiler to determine that variable's type. When you know it's a string, why not call it a string so the compiler doesn't have to do anything extra? The comment about thestruct.Name
getting converted to an alias means you are taking the actual struct from the BCL (e.g. Int32) and renaming it in a string using it's alias (e.g. int). There's nothing really wrong with this, but you can just as easily call an int "Int32" or a long "Int64" or an IntPtr "IntPtr". In changing the name to the alias, you've introduced that 64-bit bug. -
Jim Schubert over 13 yearsIn regards to your comment about class-level accessibility defaulting to private: the default access for a class if you leave off the access modifier is
internal
. My point is that I don't understand why you're "forcing the developer" to do something by generating code that will not compile... why not leave off the access modifier? Isn't that the convention used when Visual Studio generates a class stub for you? By using the private variable, you're inevitably going to cause confusion. -
Jim Schubert over 13 yearsAlso, if you find yourself using this code pretty frequently, it may be worth it to dish out $125 and by .NET Reflector Pro: red-gate.com/products/reflector Then, you will be able to analyze the exact internals of most .NET libraries. I'm sure you've already heard of it, but others reading this thread may not have.
-
John over 13 yearsMy job is not to make the job of the compiler easier. The job of the compiler is to make my life easier. I take advantage of it whenever possible if it makes sense (We use var quite often at work and it has paid off many times). Using var for strings is perfectly fine in my opinion. I could easily leave the types as what they come through but since this is intended to generate a class that the user will then incorporate into their code then it should be written as they would. Do you use "Int32 x = 5" in your code? The IntPtr is not a bug, as I said before, it will work on 32 bit.
-
John over 13 yearsI'm well aware of the benefits of reflector. We use the free version all the time. The pro version doesn't have anything additional that I would find useful. As for the private part, again you are missing the point of the code. I'll just leave it at that since this is going nowhere.
-
jpbochi over 13 years@abatishchev And your comment is just prejudice against Microsoft. It does not invalidade any word written by Eric. Someone's arguments are not made valid or invalid just because of the company he/she works for.
-
jpbochi over 13 yearsBy the way, let me make one point clear. I didn't say you should not use this ForEach extension method. I just said that you should consider the points that Eric exposed before you decide whether to use it or not. I read it and I decided not to use it. You're free to do whatever you want with your code.
-
abatishchev over 13 years@jpbochi: I respect Eric very much. Nevertheless he reads out official Microsoft team's architecture position which I called demagogy
-
csharptest.net over 13 years+1 - I generally hate extension methods for Null objects; however, this is a really nice usage!
-
chakrit over 13 yearsReactiveExtensions are made for "Reactive" programming. It, naturally, if you understands "Reactive" programming, requires the "Run()" method. There is nothing at odds between the groups. They are simply offering two different ways to code using two different frameworks.
-
Greg over 13 yearsWhy do you use
method.DynamicInvoke()
? A direct call like this:method()
is much faster. stackoverflow.com/questions/932699/… -
Roman A. Taycher over 13 yearsThe stuff I saw showing how to call a lambda used .DynamicInvoke(), I wasn't sure there was a better way.
-
Roman A. Taycher over 13 yearsWas calling DynamicInvoke() the only thing I did wrong or something else too? If it was something else I'm curious what else caused the downvotes. I appreciate the invoke explanation and would be glad to hear anything else I got wrong.
-
Greg over 13 yearsI'm not sure why this got a couple downvotes, I don't see anything wrong with the code itself. Maybe the downvoters thought that the methods weren't very C#-ish. You explain that you are borrowing from Smalltalk's style, so I don't see what's wrong with that.
-
Roman A. Taycher over 13 yearsI don't expect to use the ifTrue/ifFalse on actual code, it was just fun to implement.
-
Thomas Levesque over 13 yearsNice one! Would you know how to do the same with WPF (not using GDI)?
-
dbort over 13 yearsYou could replace everything in your
Join<T>
method with this:return string.Join(seperator, self.ToArray())
. -
19WAS85 over 13 yearsOh really, I forgot this method. Thanks, Pondidum! Edited.
-
HuseyinUslu over 13 yearsIt may be, i've not checked all the answers.
-
Jeroen Wiert Pluimers over 13 yearsAll
TryXxx
have anout
parameter andbool
result: that is the whole point of that pattern! Your method should be called something likeDefaultGetValue
to set it apart fromTryGetValue
. -
Davy8 over 13 years@Jeroen Agreed, although I'd call it
GetValueOrDefault
to be more in line with other similar methods likeFirstOrDefault
-
Shaul Behr over 13 yearsOK, point taken, I've renamed the method as @Davy8 suggested.
-
Jeroen Wiert Pluimers over 13 years@Davy8: excellent suggestion; @Shaul: thanks for fixing it (+1).
-
Nicolas Fall over 13 years@webDevHobo - System.Linq is the required using statement, also that means you have to have either linqBridge.dll or .net 3.5 or higher. Contains - msdn.microsoft.com/en-us/library/bb339118.aspx LinqBridge - code.google.com/p/linqbridge
-
Greg over 13 years@Jonathan, @Yann, @Frank @slolife, @TWith2Sugars - After reading the MSDN link (msdn.microsoft.com/en-us/library/…) provided by @slolife, I think it is safe to say that we don't have to worry about generating a new assembly on every call (as suggested by @Jonathan). I have removed the superfluous caching and cleaned up the code.
-
Alex Essilfie about 13 yearsThis is a good extension method considering
String.Replace
does not modify the source string. -
Thomas Levesque about 13 yearsHow is it different from TakeWhile? (except for the overloads with Action)
-
Pavel Hodek almost 13 yearsYes, if someone forgot "Null Object Pattern" this method is useful to patch it. Collection should never be null.
-
Espo almost 13 yearsDefault should be inclusive. If someone says to you "Pick a number between 1 and 9", both 1 and 9 is possible answers in most situations.
-
kirk.burleson almost 13 yearsI joined a new team about 5 months ago and I see this stupid ".F" method used alot. And of course they refuse to change the name...
-
JBSnorro almost 13 yearsI thought of
In<T>(...)
as well and found it to be the most useful extension method outside of the standard library. But I am at odds with the nameIn
. A method name is supposed to be describing what it does, butIn
doesn't do so. I've called itIsAnyOf<T>(...)
, but I guessIsIn<T>(...)
would be adequate as well. -
MikeKulls almost 13 yearsThis is a little excessive having something so specific available to every string object in your app. Especially when you can just use myString.Any(c => c != '0')
-
MikeKulls almost 13 yearsIt's not a plus because it will always return false on structs. That means that if someone uses it on a struct it is most likely something they did by mistake but they get no error or warning. Considering Dan's method looks identical when you call it (ie, there is no downside to using it) then there isn't any way you could consider your version a plus.
-
John Kraft almost 13 yearsI'm confused at the concern over structs. A struct, by definition, can never be null. Therefor, the fact that it returns false on a struct is correct behavior.
-
Thomas Levesque almost 13 years@MikeKulls, actually it should be
myString.All(c => c == '0')
if you want to keep the same meaning... -
Thomas Levesque almost 13 yearsIt doesn't have to be specific to persian, you can make it work for any culture (example here). Also, you should use a StringBuilder instead of string concatenation for better performance
-
Thomas Levesque almost 13 yearsEven if you cache the MethodInfo in a dictionary, calling MethodInfo.Invoke is still very slow... you should create and cache dynamically created delegates instead
-
jpbochi over 12 yearsJust found a slightly more flexible version here: stackoverflow.com/a/5807238/123897
-
demoncodemonkey over 12 years+1, I use these all the time. I was just about to post an answer with exactly the same code until I found your answer already exists :D
-
zzzzBov over 12 yearsUse an
enum
(neither
,lower
,upper
,both
) as a third parameter to specifiy equality on bounds. default toneither
. -
xxbbcc over 12 yearsIn my opinion this is really poor coding style. Constants should be used instead, not obfuscated logic.
-
leviathanbadger over 12 yearsOr even string newlines of the form
"\r\n"
. Or double newlines of the form"\n\r"
, for that matter. -
leviathanbadger over 12 yearsYou should remove the
foreach
loop and replace the body of theif
statement withyield return array[k] = array[n];
-
Thomas Levesque over 12 years@aboveyou00, for performance mostly. Also, there's no obvious equivalence between a regex and a wildcard pattern, and a wildcard is easier to use if you don't need the full power of a regex.
-
leviathanbadger over 12 yearsI don't know about calling it
Open
, but these are still good extensions and I'm surprised that nobody has posted them before. -
jeremysawesome about 12 yearsThe name makes perfect sense, especially if you've used similar functionality in MySQL. dev.mysql.com/doc/refman/5.5/en/…
-
Wolf5370 about 12 yearshahaha Just read the article (Joel's comment above) - funny true, but having been in pretty much the same boat (on the recieving end, not the Paula end) it's only funny looking back! Once had a contractor brought in to work on a project I was designigner/lead dev on - she was not under my direct control, but was assigned work from my teams work list. Bosses lauded her as being brilliant (even hiring her again later as a Dev Lead!). It never dawned on them that every piece of code she wrote or designed had not made it to production and all had to be completely rewritten from scratch by my team!
-
Wolf5370 about 12 yearsTo include names and nullable value types, I do it like this: public static void ThrowIfNull<T>(this T item, string name) where T : class {if (item == null) throw new ArgumentNullException(name);} public static void ThrowIfNull<T>(this T item) where T : class {if (item == null) throw new ArgumentNullException();} public static void ThrowIfNull<T>(this T? item, string name) where T : struct {if (item == null) throw new ArgumentNullException(name);} public static void ThrowIfNull<T>(this T? item) where T : struct {if (item == null) throw new ArgumentNullException();}