As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
There are some cool and exciting features in .NET 3.5/C# 3.0, and with those features comes some darn interesting ways to write the exact same line of code.
Using the above stated tool set (and by extension .NET 2.0 stuff), what are the different ways the below code snippet could reasonably be rewritten?
string uploadDirectory = "c:\\some\\path\\";
if (Directory.Exists(uploadDirectory)) {
string[] files = Directory.GetFiles(uploadDirectory);
foreach (string filename in files) {
if (File.GetLastWriteTime(filename).AddHours(12) < DateTime.Now) {
File.Delete(filename);
}
}
}
Lambda:
if (Directory.Exists(uploadDirectory))
Directory.GetFiles(uploadDirectory)
.Where(f => File.GetLastWriteTime(file) < DateTime.Now.AddHours(-12))
.Each(f => File.Delete(f));
Edit: On 2nd thought, you can avoid the security lookups on each File access by using DirectoryInfo and FileInfo instead of the static File methods:
var di = new DirectoryInfo(uploadDirectory);
if (di.Exists()) {
di.GetFiles()
.Where(f => f.LastWriteTime < DateTime.Now.AddHours(-12))
.Each(f=> f.Delete());
}
And for those missing their own Each method:
void Each<T>(this IEnumerable e, Action<T> action) {
foreach (T t in e) {
action(t);
}
}
To make this really crazy, and fit the C# 3.0 theme, let's throw in an anonymous type:
di.GetFiles().Select(f => new() {
Delete = f.LastWriteTime < DateTime.Now.AddHours(-12) ? f.Delete : () => { }
}).Delete();
But that just doesn't make any sense. ;)
Well, the first bit maps quite neatly to a LINQ query... but there is (deliberately) no ForEach in regular LINQ. We can annoy Eric and add one, though ;-p
So the following uses LINQ and a custom extension method - but we could re-write the exact same code (i.e. the same IL) as:
query syntax (as below)
fluent syntax (.Where().Select() ec)
explicit static (Enumerable.Where(...))
lambdas vs anonymous methods vs named methods (last changes the IL)
delegates with/without the abbreviated (C# 2.0) delegate "new" syntax
generic calls with/without generic type inference (Where() vs Where<T>())
call to File.Delete vs call to x=>File.Delete(x) etc
etc
static void Main()
{
string uploadDirectory = "c:\\some\\path\\";
if (Directory.Exists(uploadDirectory))
{
var files = from filename in Directory.GetFiles(uploadDirectory)
where File.GetLastWriteTime(filename) < DateTime.Now.AddHours(-12)
select filename;
files.ForEach(File.Delete);
}
}
static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
{
foreach (T item in items)
{
action(item);
}
}
We could write the DateTime code with a custom Expression, but that would be overkill...
However, I doubt we could ever run out of ways of writing it ;-p
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
Hello everyone I recently started using C# with unity for game development and things are coming along quite well. The problem I'm having isn't with the functionality of my code but it's more in the style of coding it. I studied ANSI C for 4 years through high school so now as I jump to C# I really can't wrap my head around using pre-made classes (besides ones that I used in C which were called libraries). At this point my code looks very similar to C with some effort at implementing OOP principles. I'm afraid that if another C# developer looked at this code, they would call it sloppy and unreadable (my C code isn't really the most elegant anyway as you'll see). I've been a lone wolf trying my best to teach myself in hopes of becoming an indie developer. so I don't have experience with team based assignments. Here's a sample of a method in my application:
public void create_item(string item_name,char L_M_H,int item_cat)//function not finshed july 13th 2013 8:07pm other fuel items need to be finished. due july 14th 10:00pm
{
int i = 0;
if(item_cat == FUEL)
{
print("item_cat is fuel");
if(L_M_H == L)
{
for(i = 0;i < 5;i++)
{//increments if fuel index has a value
if(l_fuel[i] != null)
continue;
if(l_fuel[i] == null)
{
l_fuel[i] = item_name;
Debug.Log (string.Format("Low Class Fuel: {0} Created",l_fuel[i]));
break;
}
}
}
if(L_M_H == M)
{
for(i = 0; i < 5; i++)
{
if(m_fuel[i] != null)
{
continue;
}
if(m_fuel[i] == null)
{
m_fuel[i] = item_name;
}
}
}
}
}
I'm sure there's a better way to perform functions like this in C#, however is it worth it to stop development to use classes and C# specific types like List to perform these tasks? I'm very interested in getting opinions from seasoned programmers as I'm a total noob in C# and OOP.
Yes, your code is sloppy and unreadable.
1 - Respect the C# Naming Conventions:
Your method and member names should be ProperCased, so it's public void CreateItem()
2 - Do not use primitive types where they don't belong.
Both parameters char L_M_H and int item_cat seem to be used here to emulate Enums.
3 - As other have mentioned in comments, your m_fuel and l_fuel things look strange. Make sure you create a proper data model to represent your data.
4 - Do not use for to iterate collections. Use foreach or LINQ.
public interface IFuelUpdater {
void UpdateFuelItemContainerSlots(string[] container, string itemName);
}
public class MediumOrLowFuelUpdater : IFuelUpdater {
public void UpdateFuelItemContainerSlots(string[] container, string itemName){
for(i = 0; i < container.Length; i++)
{
if(container[i] == null)
{
container[i] = item_name;
}
}
}
}
// elsewhere
IFuelUpdater updater = new MediumOrLowFuelUpdater();
string[] mediumContainer = new string[6];
string[] lowContainer = new string[6];
updater.UpdateFuelItemSlots(mediumContainer, "*Name Goes Here*");
updater.UpdateFuelItemSlots(lowContainer, "*Low Name Goes Here*");
This is how your code might look if it were made more OOP. This example is pretty nonsensical. I imagine that you really only have only one logical "fuel" array but perhaps you are forced to have two in your code because of some improper design elsewhere or some pre-optimization.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I was reading an old post from coding horror (http://www.codinghorror.com/blog/2007/02/why-cant-programmers-program.html) It's still a very entertaining read, you'll notice a lot of the people providing answers actually made small logical errors themselves (about 30% of them).
Anyway, thought I'll set myself a small challenge and found a bunch of fizzbuzz questions here: Alternate FizzBuzz Questions
"Reverse a String" - with all the built-in methods in the .net framework there are many ways to do this.
My question is:
1. how do you reverse a string using LINQ?
2. can you come up with other interesting ways of reversing a string in C#?
Here's are two examples I came up with
1. completely from scratch
2. using enumerable's reverse methods (1 liner)
private static string FromScratchSimplified(string input)
{
// constructed reversed char array
char[] reversedCharArray = new char[input.Length];
for (int i = 0; i < input.Length; i++)
{
reversedCharArray[i] = input[input.Length-1-i];
}
// build string from char array
string reversedString = new String(reversedCharArray);
return reversedString;
}
private static string UsingEnumerableReverseMethod(string input)
{
// using Enumerable.Reverse method
return new String(input.Reverse().ToArray());
}
Any more?
new string(Enumerable.Range(1, input.Length).Select(i => input[input.Length - i]).ToArray())
To keep it as close to query syntax as possible:
given:
string aString = "please reverse me";
then:
var reversed = new string((from c in aString.Select((value, index) => new { value, index })
orderby c.index descending
select c.value).ToArray());
Console.WriteLine(reversed);
yields:
em esrever esaelp
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I've got a coding style question. Below are two looping functions that do the same thing but with a slightly different loop exit technique. I just wanted to get a sense of what you guys prefer.
I personally prefer the first. I don't see why I should declare a new variable and break a loop when I know there's nothing else to be done.
private SomeObj getSomeObj(ArrayList<SomeObj> items, String type)
{
for (SomeObj someObj : items) {
if ( someObj.getField().equals(type) ) {
return someObj;
}
}
return null;
}
private SomeObj getSomeObj(ArrayList<SomeObj> items, String type)
{
SomeObj found = null
for (SomeObj someObj : items) {
if ( someObj.getField().equals(type) ) {
found = someObj;
break;
}
}
return found;
}
Both have different purposes. They are not replacements for each other.
First one comes out from the method
Second one comes out from the loop NOT method.
Let us say if there is some code which manipulates SomeObj after the for loop, then results will differ from first method to second method.
I prefer the first. In general, i prefer early exits from methods as it tends to reduce nesting.
Both approaches could not replace each other in every situation. Suppose you want to execute the code after loop finishes then return could not do that for you and vice versa. In your case both could be used but not in every situation.
Statements after for loop, which you do not want to execute get executed with break
private SomeObj getSomeObj(ArrayList<SomeObj> items, String type)
{
SomeObj found = null
for (SomeObj someObj : items) {
if ( someObj.getField().equals(type) ) {
found = someObj;
break;
}
}
//Statements you do not want to execute get executed with break
return found;
}
Statements after for loop, which you want to execute do not get executed with return
private SomeObj getSomeObj(ArrayList<SomeObj> items, String type)
{
SomeObj found = null
for (SomeObj someObj : items) {
if ( someObj.getField().equals(type) ) {
found = someObj;
return;
}
}
//Statements you want to execute do not get executed with return
return found;
}
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I have always hated string parsing, something I am doing a lot of in a current project.
Does c# have and tricks or quick features for strings that would make my life easier? In particular cropping, multiplying or substringing? The end goal here is to take a list of string and turn it into a nice pretty columned structure. Easy, but still, I would it to be python easy.
For example, python has:
>>> a = "I once was a string, then I got mutilated"
>>> print a[20:]
then I got mutilated
or
>>> 'chicken' in 'chicken noodle soup'
True
or finally
>>> 'lol' * 5
'lollollollollol'
There aren't language related features for this in C# like there are in Python. The only real C# language feature with strings is allowing + to be mapped to String.Concat, to simplify (and keep efficient) "a" + "b" + "c" statements.
The String class provides this functionality via methods, however. There is also StringBuilder, which is used for building large strings based on multiple concatenations.
In your example, see String.Substring for slicing and String.Contains for in. There isn't a simple "repeat" style operation like the multiplication in Python.
That being said, it's easy to make an extension method which handles the multiply functionality.
They're different languages - the syntax is different and comparing C# to Python in this way is largely pointless. Also I completely challenge your assertion that the examples you've given are 'easier'.
I don't see how you can get much easier than:
Console.WriteLine("Foo".Substring(1)); //<-- prints 'oo'
Console.WriteLine("chicken noodle soup".Contains("chicken")
.ToString()); //<-- prints 'true'
And for the last one, read this SO: Can I "multiply" a string (in C#)?
Personally, in particular, I hate the idea of multiplying a string - too much ambiguity if that value happens to be '5' - hiding such functionality behind operators smells.
First Question
You can use String.SubString():
string a = "I once was a string, then I got mutilated";
string lastTwentyCharactersOfA = a.Substring(Math.Max(0, a.Length - 20));
// returns "then I got mutilated"
Credit where credit is due: This answer does a nice job of making sure that you don't get an exception if your string has less characters than you are requesting.
Second Question
You can use String.Contains():
string soup = "chicken noodle soup";
bool soupContainsChicken = soup.Contains("chicken"); // returns True
Third Question
You can't override the multiplication operator for the String class. It's a sealed class, and of course you don't have access to the source code to make it a partial class or something along those lines. You have a couple of options that will get you close to what you want to do. One is to write an extension method:
public static string MultiplyBy(this string s, int times)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < times; i++)
{
sb.Append(s);
}
return sb.ToString();
}
Usage:
string lol = "lol";
string trololol = lol.MultiplyBy(5); // returns "lollollollollol"
Or if you want to go the route of operator overloading, you can write a custom String class of sorts and then have at it.
public struct BetterString // probably not better than System.String at all
{
public string Value { get; set; }
public static BetterString operator *(BetterString s, int times)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < times; i++)
{
sb.Append(s.Value);
}
return new BetterString { Value = sb.ToString() };
}
}
Usage:
BetterString lol = new BetterString { Value = "lol" };
BetterString trololol = lol * 5; // trololol.Value is "lollollollollol"
In general, there's a lot you can do with System.String and System.Text.StringBuilder. And the possibilities are almost endless with extension methods. Check out MSDN if you are interested in learning the ins and outs of it all.
using linq, you can treat your string like a list of chars and do what you want easy enough.
var chickenString = "chicken noodle soup";
var hasChicken = chickenString.Contains("chicken");
// hasChicken = true at this point...
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why is there not a ForEach extension method on the IEnumerable interface?
I've noticed when writing LINQ-y code that .ForEach() is a nice idiom to use. For example, here is a piece of code that takes the following inputs, and produces these outputs:
{ "One" } => "One"
{ "One", "Two" } => "One, Two"
{ "One", "Two", "Three", "Four" } => "One, Two, Three and Four";
And the code:
private string InsertCommasAttempt(IEnumerable<string> words)
{
List<string> wordList = words.ToList();
StringBuilder sb = new StringBuilder();
var wordsAndSeparators = wordList.Select((string word, int pos) =>
{
if (pos == 0) return new { Word = word, Leading = string.Empty };
if (pos == wordList.Count - 1) return new { Word = word, Leading = " and " };
return new { Word = word, Leading = ", " };
});
wordsAndSeparators.ToList().ForEach(v => sb.Append(v.Leading).Append(v.Word));
return sb.ToString();
}
Note the interjected .ToList() before the .ForEach() on the second to last line.
Why is it that .ForEach() isn't available as an extension method on IEnumerable<T>? With an example like this, it just seems weird.
Because ForEach(Action) existed before IEnumerable<T> existed.
Since it was not added with the other extension methods, one can assume that the C# designers felt it was a bad design and prefer the foreach construct.
Edit:
If you want you can create your own extension method, it won't override the one for a List<T> but it will work for any other class which implements IEnumerable<T>.
public static class IEnumerableExtensions
{
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (T item in source)
action(item);
}
}
According to Eric Lippert, this is mostly for philosophical reasons. You should read the whole post, but here's the gist as far as I'm concerned:
I am philosophically opposed to
providing such a method, for two
reasons.
The first reason is that doing so
violates the functional programming
principles that all the other sequence
operators are based upon. Clearly the
sole purpose of a call to this method
is to cause side effects.
The purpose of an expression is to
compute a value, not to cause a side
effect. The purpose of a statement is
to cause a side effect. The call site
of this thing would look an awful lot
like an expression (though,
admittedly, since the method is
void-returning, the expression could
only be used in a “statement
expression” context.)
It does not sit well with me to make
the one and only sequence operator
that is only useful for its side
effects.
The second reason is that doing so
adds zero new representational power
to the language.
Because ForEach() on an IEnumerable is just a normal for each loop like this:
for each T item in MyEnumerable
{
// Action<T> goes here
}
ForEach isn't on IList it's on List. You were using the concrete List in your example.
I am just guessing here , but putting foreach on IEnumerable would make operations on it to have side effects . None of the "available" extension methods cause side effects , putting an imperative method like foreach on there would muddy the api I guess . Also, foreach would initialize the lazy collection .
Personally I've been fending off the temptation to just add my own , just to keep side effect free functions separate from ones with side effects.
ForEach is implemented in the concrete class List<T>
Just a guess, but List can iterate over its items without creating an enumerator:
public void ForEach(Action<T> action)
{
if (action == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
for (int i = 0; i < this._size; i++)
{
action(this._items[i]);
}
}
This can lead to better performance. With IEnumerable, you don't have the option to use an ordinary for-loop.
LINQ follows the pull-model and all its (extension) methods should return IEnumerable<T>, except for ToList(). The ToList() is there to end the pull-chain.
ForEach() is from the push-model world.
You can still write your own extension method to do this, as pointed out by Samuel.
I honestly don't know for sure why the .ForEach(Action) isn't included on IEnumerable but, right, wrong or indifferent, that's the way it is...
I DID however want to highlight the performance issue mentioned in other comments. There is a performance hit based on how you loop over a collection. It is relatively minor but nevertheless, it certainly exists. Here is an incredibly fast and sloppy code snippet to show the relations... only takes a minute or so to run through.
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Start Loop timing test: loading collection...");
List<int> l = new List<int>();
for (long i = 0; i < 60000000; i++)
{
l.Add(Convert.ToInt32(i));
}
Console.WriteLine("Collection loaded with {0} elements: start timings",l.Count());
Console.WriteLine("\n<===============================================>\n");
Console.WriteLine("foreach loop test starting...");
DateTime start = DateTime.Now;
//l.ForEach(x => l[x].ToString());
foreach (int x in l)
l[x].ToString();
Console.WriteLine("foreach Loop Time for {0} elements = {1}", l.Count(), DateTime.Now - start);
Console.WriteLine("\n<===============================================>\n");
Console.WriteLine("List.ForEach(x => x.action) loop test starting...");
start = DateTime.Now;
l.ForEach(x => l[x].ToString());
Console.WriteLine("List.ForEach(x => x.action) Loop Time for {0} elements = {1}", l.Count(), DateTime.Now - start);
Console.WriteLine("\n<===============================================>\n");
Console.WriteLine("for loop test starting...");
start = DateTime.Now;
int count = l.Count();
for (int i = 0; i < count; i++)
{
l[i].ToString();
}
Console.WriteLine("for Loop Time for {0} elements = {1}", l.Count(), DateTime.Now - start);
Console.WriteLine("\n<===============================================>\n");
Console.WriteLine("\n\nPress Enter to continue...");
Console.ReadLine();
}
Don't get hung up on this too much though. Performance is the currency of application design but unless your application is experiencing an actual performance hit that is causing usability problems, focus on coding for maintainability and reuse since time is the currency of real life business projects...
It's called "Select" on IEnumerable<T>
I am enlightened, thank you.