Top .net Questions

List of Tags
730
Ian Boyd

How can you enumerate a enum in C#?

e.g. the following does not compile:

public enum Suit
{
    Spades,
    Hearts,
    Clubs,
    Diamonds
}

public void EnumerateAllSuitsDemoMethod()
{
    foreach (Suit suit in Suit)
    {
        DoSomething(suit);
    }
}

It gives the compile time error:

'Suit' is a 'type' but is used like a 'variable'

It fails on the Suit keyword, the 2nd one.

Answered By: jop ( 1105)
foreach (Suit suit in Enum.GetValues(typeof(Suit)))
{
}
542
Jeff Atwood

Given a specific DateTime value, how do I display relative time, like

  • 2 hours ago
  • 3 days ago
  • a month ago

a la Ruby on Rail's time ago in words helper.

Answered By: Vincent Robert ( 396)

Jeff, your code is nice but could be clearer with constants (as suggested in Code Complete).

const int SECOND = 1;
const int MINUTE = 60 * SECOND;
const int HOUR = 60 * MINUTE;
const int DAY = 24 * HOUR;
const int MONTH = 30 * DAY;

if (delta < 0)
{
  return "not yet";
}
if (delta < 1 * MINUTE)
{
  return ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";
}
if (delta < 2 * MINUTE)
{
  return "a minute ago";
}
if (delta < 45 * MINUTE)
{
  return ts.Minutes + " minutes ago";
}
if (delta < 90 * MINUTE)
{
  return "an hour ago";
}
if (delta < 24 * HOUR)
{
  return ts.Hours + " hours ago";
}
if (delta < 48 * HOUR)
{
  return "yesterday";
}
if (delta < 30 * DAY)
{
  return ts.Days + " days ago";
}
if (delta < 12 * MONTH)
{
  int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
  return months <= 1 ? "one month ago" : months + " months ago";
}
else
{
  int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
  return years <= 1 ? "one year ago" : years + " years ago";
}
481
Jeff Atwood

Given a DateTime representing a person's birthday, how do I calculate their age?

Answered By: Mike Polen ( 511)

For some reason Jeff's code didn't seem simple enough. To me this seems simpler and easier to understand:

DateTime today = DateTime.Today;
int age = today.Year - bday.Year;
if (bday > today.AddYears(-age)) age--;

Caution!

This ancient question is from the early days of Stack Overflow, and while we recognize its historical significance and have thus chosen to keep it around, please realize that if a question like this were to be asked today, it is very likely to be closed by the current community of users.

Please feel free to read and learn from the answers to this question, but refrain from asking similar questions just because this one exists.

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.

Answered By: Winston Smith ( 232)
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....
}
476
Paul Stovell

When building console applications that take parameters, you can use the arguments passed to Main(string[] args).

In the past I've simply indexed/looped that array and done a few regular expressions to extract the values. However, when the commands get more complicated, the parsing can get pretty ugly.

So I'm interested in:

  • Libraries that you use
  • Patterns that you use

Assume the commands always adhere to common standards such as answered here.

Answered By: jonp ( 235)

I would strongly suggest using NDesk.Options (Documentation) and/or Mono.Options (same API, different namespace). An example from the documentation:

bool show_help = false;
List<string> names = new List<string> ();
int repeat = 1;

var p = new OptionSet () {
    { "n|name=", "the {NAME} of someone to greet.",
       v => names.Add (v) },
    { "r|repeat=", 
       "the number of {TIMES} to repeat the greeting.\n" + 
          "this must be an integer.",
        (int v) => repeat = v },
    { "v", "increase debug message verbosity",
       v => { if (v != null) ++verbosity; } },
    { "h|help",  "show this message and exit", 
       v => show_help = v != null },
};

List<string> extra;
try {
    extra = p.Parse (args);
}
catch (OptionException e) {
    Console.Write ("greet: ");
    Console.WriteLine (e.Message);
    Console.WriteLine ("Try `greet --help' for more information.");
    return;
}
451
Eren Ers&#246;nmez

I wrote some code for testing the impact of try-catch, but seeing some surprising results.

static void Main(string[] args)
{
    Thread.CurrentThread.Priority = ThreadPriority.Highest;
    Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;

    long start = 0, stop = 0, elapsed = 0;
    double avg = 0.0;

    long temp = Fibo(1);

    for (int i = 1; i < 100000000; i++)
    {
        start = Stopwatch.GetTimestamp();
        temp = Fibo(100);
        stop = Stopwatch.GetTimestamp();

        elapsed = stop - start;
        avg = avg + ((double)elapsed - avg) / i;
    }

    Console.WriteLine("Elapsed: " + avg);
    Console.ReadKey();
}

static long Fibo(int n)
{
    long n1 = 0, n2 = 1, fibo = 0;
    n++;

    for (int i = 1; i < n; i++)
    {
        n1 = n2;
        n2 = fibo;
        fibo = n1 + n2;
    }

    return fibo;
}

On my computer, this consistently prints out a value around 0.96..

When I wrap the for loop inside Fibo() with a try-catch block like this:

static long Fibo(int n)
{
    long n1 = 0, n2 = 1, fibo = 0;
    n++;

    try
    {
        for (int i = 1; i < n; i++)
        {
            n1 = n2;
            n2 = fibo;
            fibo = n1 + n2;
        }
    }
    catch {}

    return fibo;
}

Now it consistently prints out 0.69... -- it actually runs faster! But why?

Note: I compiled this using the Release configuration and directly ran the EXE file (outside Visual Studio).

EDIT: Jon Skeet's excellent analysis shows that try-catch is somehow causing the x86 CLR to use the CPU registers in a more favorable way in this specific case (and I think we're yet to understand why). I confirmed Jon's finding that x64 CLR doesn't have this difference, and that it was faster than the x86 CLR. I also tested using int types inside the Fibo method instead of long types, and then the x86 CLR was as equally fast as the x64 CLR.

Answered By: Jon Skeet ( 352)

Well, the way you're timing things looks pretty nasty to me. It would be much more sensible to just time the whole loop:

var stopwatch = Stopwatch.StartNew();
for (int i = 1; i < 100000000; i++)
{
    Fibo(100);
}
stopwatch.Stop();
Console.WriteLine("Elapsed time: {0}", stopwatch.Elapsed);

That way you're not at the mercy of tiny timings, floating point arithmetic and accumulated error.

Having made that change, see whether the "non-catch" version is still slower than the "catch" version.

EDIT: Okay, I've tried it myself - and I'm seeing the same result. Very odd. I wondered whether the try/catch was disabling some bad inlining, but using [MethodImpl(MethodImplOptions.NoInlining)] instead didn't help...

Basically you'll need to look at the optimized JITted code under cordbg, I suspect...

EDIT: A few more bits of information:

  • Putting the try/catch around just the n++; line still improves performance, but not by as much as putting it around the whole block
  • If you catch a specific exception (ArgumentException in my tests) it's still fast
  • If you print the exception in the catch block it's still fast
  • If you rethrow the exception in the catch block it's slow again
  • If you use a finally block instead of a catch block it's slow again
  • If you use a finally block as well as a catch block, it's fast

Weird...

EDIT: Okay, we have disassembly...

This is using the C# 2 compiler and .NET 2 (32-bit) CLR, disassembling with mdbg (as I don't have cordbg on my machine). I still see the same performance effects, even under the debugger. The fast version uses a try block around everything between the variable declarations and the return statement, with just a catch{} handler. Obviously the slow version is the same except without the try/catch. The calling code (i.e. Main) is the same in both cases, and has the same assembly representation (so it's not an inlining issue).

Disassembled code for fast version:

 [0000] push        ebp
 [0001] mov         ebp,esp
 [0003] push        edi
 [0004] push        esi
 [0005] push        ebx
 [0006] sub         esp,1Ch
 [0009] xor         eax,eax
 [000b] mov         dword ptr [ebp-20h],eax
 [000e] mov         dword ptr [ebp-1Ch],eax
 [0011] mov         dword ptr [ebp-18h],eax
 [0014] mov         dword ptr [ebp-14h],eax
 [0017] xor         eax,eax
 [0019] mov         dword ptr [ebp-18h],eax
*[001c] mov         esi,1
 [0021] xor         edi,edi
 [0023] mov         dword ptr [ebp-28h],1
 [002a] mov         dword ptr [ebp-24h],0
 [0031] inc         ecx
 [0032] mov         ebx,2
 [0037] cmp         ecx,2
 [003a] jle         00000024
 [003c] mov         eax,esi
 [003e] mov         edx,edi
 [0040] mov         esi,dword ptr [ebp-28h]
 [0043] mov         edi,dword ptr [ebp-24h]
 [0046] add         eax,dword ptr [ebp-28h]
 [0049] adc         edx,dword ptr [ebp-24h]
 [004c] mov         dword ptr [ebp-28h],eax
 [004f] mov         dword ptr [ebp-24h],edx
 [0052] inc         ebx
 [0053] cmp         ebx,ecx
 [0055] jl          FFFFFFE7
 [0057] jmp         00000007
 [0059] call        64571ACB
 [005e] mov         eax,dword ptr [ebp-28h]
 [0061] mov         edx,dword ptr [ebp-24h]
 [0064] lea         esp,[ebp-0Ch]
 [0067] pop         ebx
 [0068] pop         esi
 [0069] pop         edi
 [006a] pop         ebp
 [006b] ret

Disassembled code for slow version:

 [0000] push        ebp
 [0001] mov         ebp,esp
 [0003] push        esi
 [0004] sub         esp,18h
*[0007] mov         dword ptr [ebp-14h],1
 [000e] mov         dword ptr [ebp-10h],0
 [0015] mov         dword ptr [ebp-1Ch],1
 [001c] mov         dword ptr [ebp-18h],0
 [0023] inc         ecx
 [0024] mov         esi,2
 [0029] cmp         ecx,2
 [002c] jle         00000031
 [002e] mov         eax,dword ptr [ebp-14h]
 [0031] mov         edx,dword ptr [ebp-10h]
 [0034] mov         dword ptr [ebp-0Ch],eax
 [0037] mov         dword ptr [ebp-8],edx
 [003a] mov         eax,dword ptr [ebp-1Ch]
 [003d] mov         edx,dword ptr [ebp-18h]
 [0040] mov         dword ptr [ebp-14h],eax
 [0043] mov         dword ptr [ebp-10h],edx
 [0046] mov         eax,dword ptr [ebp-0Ch]
 [0049] mov         edx,dword ptr [ebp-8]
 [004c] add         eax,dword ptr [ebp-1Ch]
 [004f] adc         edx,dword ptr [ebp-18h]
 [0052] mov         dword ptr [ebp-1Ch],eax
 [0055] mov         dword ptr [ebp-18h],edx
 [0058] inc         esi
 [0059] cmp         esi,ecx
 [005b] jl          FFFFFFD3
 [005d] mov         eax,dword ptr [ebp-1Ch]
 [0060] mov         edx,dword ptr [ebp-18h]
 [0063] lea         esp,[ebp-4]
 [0066] pop         esi
 [0067] pop         ebp
 [0068] ret

In each case the * shows where the debugger entered in a simple "step-into".

EDIT: Okay, I've now looked through the code and I think I can see how each version works... and I believe the slower version is slower because it uses fewer registers and more stack space. For small values of n that's possibly faster - but when the loop takes up the bulk of the time, it's slower.

Possibly the try/catch block forces more registers to be saved and restored, so the JIT uses those for the loop as well... which happens to improve the performance overall. It's not clear whether it's a reasonable decision for the JIT to not use as many registers in the "normal" code.

EDIT: Just tried this on my x64 machine. The x64 CLR is much faster (about 3-4 times faster) than the x86 CLR on this code, and under x64 the try/catch block doesn't make a noticeable difference.

426
Alison

I want to do something like:

myObject myObj = GetmyObj(); //Create and fill a new object
myObject newObj = myObj.Clone();

And then make changes to the new object that are not reflected in the original object.

I don't often need this functionality, so when it's been necessary, I've resorted to creating a new object and then copying each property individually, but it always leaves me with the feeling that there is a better or more elegant way of handling the situation.

How can I clone or deep copy an object so that the cloned object can be modified without any changes being reflected in the original object?

Answered By: johnc ( 440)

Whilst the standard practice is to implement the ICloneable interface (described here, so I won't regurgitate), here's a nice deep clone object copier I found on The Code Project a while ago and incorporated it in our stuff.

As mentioned elsewhere, it does require your objects to be serializable.

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

/// <summary>
/// Reference Article http://www.codeproject.com/KB/tips/SerializedObjectCloner.aspx
/// Provides a method for performing a deep copy of an object.
/// Binary Serialization is used to perform the copy.
/// </summary>
public static class ObjectCopier
{
    /// <summary>
    /// Perform a deep Copy of the object.
    /// </summary>
    /// <typeparam name="T">The type of object being copied.</typeparam>
    /// <param name="source">The object instance to copy.</param>
    /// <returns>The copied object.</returns>
    public static T Clone<T>(T source)
    {
        if (!typeof(T).IsSerializable)
        {
            throw new ArgumentException("The type must be serializable.", "source");
        }

        // Don't serialize a null object, simply return the default for that object
        if (Object.ReferenceEquals(source, null))
        {
            return default(T);
        }

        IFormatter formatter = new BinaryFormatter();
        Stream stream = new MemoryStream();
        using (stream)
        {
            formatter.Serialize(stream, source);
            stream.Seek(0, SeekOrigin.Begin);
            return (T)formatter.Deserialize(stream);
        }
    }
}

The idea is that it serializes your object and then deserializes it into a fresh object. The benefit is that you don't have to concern yourself about cloning everything when an object gets too complex.

And with the use of extension methods (also from the originally referenced source):

In case you prefer to use the new extension methods of C# 3.0, change the method to have the following signature:

public static T Clone<T>(this T source)
{
   //...
}

Now the method call simply becomes objectBeingCloned.Clone();.

I have been running StyleCop over some C# code and it keeps reporting that my using statements should be inside the namespace.

Is there a technical reason for putting the using statements inside instead of outside the namespace?

Answered By: Charlie ( 533)

There is actually a (subtle) difference between the two. Imagine you have the following code in File1.cs:

// File1.cs
using System;
namespace Outer.Inner
{
    class Foo
    {
        static void Bar()
        {
            double d = Math.PI;
        }
    }
}

Now imagine that someone adds another file (File2.cs) to the project that looks like this:

// File2.cs
namespace Outer
{
    class Math
    {
    }
}

The compiler searches Outer before looking at those using statements outside the namespace, so it finds Outer.Math instead of System.Math. Unfortunately (or perhaps fortunately?), Outer.Math has no PI member, so File1 is now broken.

This changes if you put the using inside your namespace declaration, as follows:

// File1b.cs
namespace Outer.Inner
{
    using System;
    class Foo
    {
        static void Bar()
        {
            double d = Math.PI;
        }
    }
}

Now the compiler searches System before searching Outer, finds System.Math, and all is well.

Some would argue that Math might be a bad name for a user-defined class, since there's already one in System; the point here is just that there is a difference, and it affects the maintainability of your code.

It's also interesting to note what happens if Foo is in namespace Outer, rather than Outer.Inner. In that case, adding Outer.Math in File2 breaks File1 regardless of where the using goes. This implies that the compiler searches the innermost enclosing namespace before it looks at any using statements.

408
mistrmark

What is the best tool for creating an Excel Spreadsheet with C#?

Ideally, I would like open source so I don't have to add any third party dependencies to my code, and I would like to avoid using Excel directly to create the file (using OLE Automation.)

The .CSV file solution is easy, and is the current way I am handling this, but I would like to control the output formats.


EDIT: I am still looking at these to see the best alternative for my solution. Interop will work, but it requires Excel to be on the machine you are using. Also the OLEDB method is intriguing, but may not yield much more than what I can achieve with CSV files. I will look more into the 2003 xml format, but that also puts a > Excel 2003 requirement on the file.

I am currently looking at a port of the PEAR (PHP library) Excel Writer that will allow some pretty good XLS data and formatting and it is in the Excel_97 compatible format that all modern versions of Excel support. The PEAR Excel Writer is here: PEAR - Excel Writer

Answered By: Mike Webb ( 218)

You can use a library called ExcelLibrary. It's a free, open source library posted on Google Code:

ExcelLibrary

This looks to be a port of the PHP ExcelWriter that you mentioned above. It will not write to the new .xlsx format yet, but they are working on adding that functionality in.

It's very simple, small and easy to use. Plus it has a DataSetHelper that lets you use DataSets and DataTables to easily work with Excel data.

ExcelLibrary seems to still only work for the older Excel format (.xls files), but may be adding support in the future for newer 2007/2010 formats.

You can also use EPPlus, which works only for Excel 2007/2010 format files (.xlsx files).

There are a few known bugs with each library as noted in the comments. In all, EPPlus seems to be the best choice as time goes on. It seems to be more actively updated and documented as well.

Also, as noted by @АртёмЦарионов below, EPPlus has support for Pivot Tables and ExcelLibrary may have some support (Pivot table issue in ExcelLibrary)

Here are a couple links for quick reference:
ExcelLibrary - GNU Lesser GPL
EPPlus - GNU Library General Public License (LGPL)

Here some example code for ExcelLibrary:

Here is an example taking data from a database and creating a workbook from it. Note that the ExcelLibrary code is the single line at the bottom:

//Create the data set and table
DataSet ds = new DataSet("New_DataSet");
DataTable dt = new DataTable("New_DataTable");

//Set the locale for each
ds.Locale = System.Threading.Thread.CurrentThread.CurrentCulture;
dt.Locale = System.Threading.Thread.CurrentThread.CurrentCulture;

//Open a DB connection (in this example with OleDB)
OleDbConnection con = new OleDbConnection(dbConnectionString);
con.Open();

//Create a query and fill the data table with the data from the DB
string sql = "SELECT Whatever FROM MyDBTable;";
OleDbCommand cmd = new OleDbCommand(sql, con);
OleDbDataAdapter adptr = new OleDbDataAdapter();

adptr.SelectCommand = cmd;
adptr.Fill(dt);
con.Close();

//Add the table to the data set
ds.Tables.Add(dt);

//Here's the easy part. Create the Excel worksheet from the data set
ExcelLibrary.DataSetHelper.CreateWorkbook("MyExcelFile.xls", ds);

Creating the Excel file is as easy as that. You can also manually create Excel files, but the above functionality is what really impressed me.

405
c#, .net
Tom

What is the difference between Decimal, Float and Double in C#?

When would someone use one of these?

Answered By: Jon Skeet ( 615)

float and double are floating binary point types. In other words, they represent a number like this:

10001.10010110011

The binary number and the location of the binary point are both encoded within the value.

decimal is a floating decimal point type. In other words, they represent a number like this:

12345.65789

Again, the number and the location of the decimal point are both encoded within the value – that's what makes decimal still a floating point type instead of a fixed point type.

The important thing to note is that humans are used to representing non-integers in a decimal form, and expect exact results in decimal representations; not all decimal numbers are exactly representable in binary floating point – 0.1, for example – so if you use a binary floating point value you'll actually get an approximation to 0.1. You'll still get approximations when using a floating decimal point as well – the result of dividing 1 by 3 can't be exactly represented, for example.

As for what to use when:

  • For values which are "naturally exact decimals" it's good to use decimal. This is usually suitable for any concepts invented by humans: financial values are the most obvious example, but there are others too. Consider the score given to divers or ice skaters, for example.

  • For values which are more artefacts of nature which can't really be measured exactly anyway, float/double are more appropriate. For example, scientific data would usually be represented in this form. Here, the original values won't be "decimally accurate" to start with, so it's not important for the expected results to maintain the "decimal accuracy". Floating binary point types are much faster to work with than decimals.