2

I want to create a simple delegate in my Class below. I do not want the method that I am trying to create the delegate for to be static. I created an instance of the class A and then tried to use the variable to initiate my method and I still am receiving the error.

Question: How can I make a delegate and not have to make the method a static method?

Code:

public class A : System.Object
{
    A a = new A();

    public delegate void myMethod(int SomeInt);
    myMethod Temp = a.add;

    public void add(int a) 
    { 
    }

    public virtual void DoTest()
    {
    }
}

Error:

Error   6   A field initializer cannot reference the non-static field, method, or property 'FlowControl.A.a'    C:\Users\itpr13266\AppData\Local\Temporary Projects\FlowControl\Program.cs  170 25  FlowControl
  • Just a pointer to [why can't a delegate refer to a non-static method when used in static method](http://stackoverflow.com/questions/2298997/why-cant-a-delegate-refer-to-a-non-static-method-when-used-in-a-static-method) or [build a static delegate from non-static-method](http://stackoverflow.com/questions/4083028/build-a-static-delegate-from-non-static-method) or [pass-delegate-to-a-method-where-delegates-are-non-static](http://stackoverflow.com/questions/4357480/how-pass-delegate-to-a-method-where-delegates-are-non-static) – surfmuggle Apr 22 '14 at 18:27

4 Answers4

1

you don't need to make is static.just do this in your constructor:

myMethod Temp = a.add;

Like:

private myMethod Temp;

public A()
{
   Temp = a.add;
}
Selman Genç
  • 100,147
  • 13
  • 119
  • 184
1

It's the initialization that breaks up, not the non-static delegate itself.

public delegate void myMethod(int SomeInt);
//myMethod Temp = a.add;
myMethod Temp;

public A() 
{ 
    Temp = a.add;  // in a constructor it does work 
}
H H
  • 263,252
  • 30
  • 330
  • 514
1

Anytime you initialize a variable in its declaration (field initialization) you have two options:

  1. Initialize it to some constant
  2. Initialize it to something static

So to make what you are doing work, a method needs to perform the assignment (likely your constructor):

public A()
{
   Temp = a.Add;
}

This actually isn't specific to delegates, any initialization like that would not work.

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
0

In some languages such as VB.NET, in-line initialization of fields takes place after a base object's constructor has run. In such languages, such declarations may refer to the object under construction. In C#, however, the field initializations are done before execution of the base constructor. Because constructing a delegate would allow code to get a reference to the base object, the C# compiler won't allow such operations until after the base constructor has been invoked. It doesn't matter whether the method used by the delegate would access any virtual or base-class members, since the compiler would in general have no way of knowing whether code which received the delegate might manage to extract the Target, cast it to the proper type, and access its members before the base-class constructor has run.

Personally, I prefer the late-initialization approach since there are many cases where a field's initial value should depend upon other fields, and far fewer where a field can be usefully initialized without having to know the values of at least some other fields or constructor parameters. Nonetheless, because C# is defined as it is, one must generally assign fields in constructors rather than with initializations, even in cases where the field will be assigned once and never rewritten.

Incidentally, if the outside world is required to use uses factory methods rather than exposed constructors to make instances of one's class, one may have such methods pass constructor parameters using ThreadStatic variables. This is a bit icky, but can make in-line field initializations much more usable. It won't be possible to smoothly assign delegates in-line, but if a field initialization expression needs to pass a delegate to a method that must run before the base constructor, one could use a helper class and factory method to build "indirect delegates", so your initializer could use something like thing myField = methodNeedingActionOfInt(actionHelper.MakeAction<int>( (myClass it)=>it.someMethodTakingInt));, where actionHelper is a ThreadStatic field which is partially set up in the factory method, and finished in the base constructor, but I don't know any way to do that cleanly enough to be worthwhile.

supercat
  • 77,689
  • 9
  • 166
  • 211