views:

151

answers:

4

I am not sure what exactly the issue is here. I am working with 2 strings and I keeping getting the error "A field initializer cannot reference the non-static field, method, or property 'Captcha.Capture.CaptureTime'".

Here's a snippet from the code:

string CaptureTime = DateTime.Now.Month.ToString() + "-" + DateTime.Now.Day.ToString() + "-" + DateTime.Now.Year.ToString() + "-" + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString();


string SaveFormat = Properties.Settings.Default.SaveFolder + "Screenshot (" + CaptureTime + ")." + Properties.Settings.Default.ImageFormat;

I won't go into detail as to why I am using the strings in this particular way. Everything works fine. I'm guessing it has something to do with a string being within another string? It might be completely obvious but I really have no clue. Any ideas?

+3  A: 

The error tells you exactly what is happening. You are trying to initialize the instance field SaveFormat with a value that depends on the instance field CaptureTime using field-initializer syntax. Move the initialization of these values into an instance-level constructor and you will be okay.

By the way, save off DateTime.Now in a temp value instead of repeatedly calling as you currently are. What if you roll over a date boundary while your code is executing? Yuck.

Jason
+1  A: 

It is forbidden in C# to write non-static field initializers that reference each other, since normally order of initialization is undefined.

Move initialization to constructor of your class

And you really better to use String.Format or DateTime.Format(string) for date formatting.

elder_george
+1 Thanks, this answered my question; didn't know that instance field initializers were non-deterministic-
Gurdas Nijor
+7  A: 

No, it's nothing to do with that - it's just that instance field initializers can't use other instance fields or instance methods. Here's a simple example:

class Test 
{
    int x = 0;
    int y = x + 1;
}

It's probably simplest to move the initialization into a constructor body instead. By the way, you shouldn't access DateTime.Now several times like that in one initializer - it could change between calls, leading to horrible results. Use a local variable instead - which again is easier done from a constructor:

string CaptureTime;
string SaveFormat;

public YourType()
{
    DateTime now = DateTime.Now;

    CaptureTime = now.Month + "-" + now.Day + "-" + now.Year + "-" + 
        now.Hour.ToString() + now.Minute.ToString() + now.Second.ToString();
    SaveFormat = Properties.Settings.Default.SaveFolder + 
        "Screenshot (" + CaptureTime + ")." + 
        Properties.Settings.Default.ImageFormat;
}

By the way, a simpler way to produce CaptureTime would be:

CaptureTime = now.ToString("MM-dd-yyyy-HHmmss");
Jon Skeet
In fact, it *will* change between calls won't it? And I seem to recall hearing that `DateTime.Now` was 'slow' besides that.
Matthew Scharley
It may do - it may not. It's not fine-grained enough to guarantee a change between calls. Even if it does change, it's only *some* changes which would be problematic - basically if the "second" changes from 59 to 00 after you've evaluated "minute", or similar.
Jon Skeet
A: 

You need to set the member in the constructor, or assign it through a property.

Btw, you could clean that up that DateTime code using ToString overload.

string CaptureTime = DateTime.Now.ToString("your format");
Si