1

In implementing IDataErrorInfo the following code compiles and works without a problem:

public string Error
        {
            get { return null; }
        }

        public string this[string columnName]
        {
            get
            {
                switch (columnName)
                {
                    case "MemberId":            return validate(MemberId,           0, RegexLibrary.NonEmptyRegex);
                    case "PolicyType":          return validate(PolicyType,         1, RegexLibrary.NonEmptyRegex);
                    case "EffectiveDateFrom":   return validate(EffectiveDateFrom,  2, RegexLibrary.DateRegex);
                    case "EffectiveDateTo":     return validate(EffectiveDateTo,    3, RegexLibrary.DateRegex);
                    case "Phone":               return validate(Phone,              4, RegexLibrary.PhoneRegex);
                    case "CompanyName":         return validate(CompanyName,        5, RegexLibrary.NonEmptyRegex);
                }
                // string.Empty is no error.
                return string.Empty;
            }
        }

 public string validate(string column, int position, string regex)
        {
            string invalid = string.Format("{0} is invalid.", column);
            if (column == null)
            {
                SetErrorStatus(1, position);
                return invalid;
            }

            Match match = Regex.Match(column, regex);
            if (!match.Success)
            {
                SetErrorStatus(1, position);
                return invalid;
            }

            SetErrorStatus(0, position);
            return string.Empty;
        }

However, If validate(...) is defined as a function like so:

Func<string, int, string, string> validate = (column, position, regex) =>
        {
            string invalid = string.Format("{0} is invalid.", column);
            if (column == null)
            {
                SetErrorStatus(1, position);
                return invalid;
            }

            Match match = Regex.Match(column, regex);
            if (!match.Success)
            {
                SetErrorStatus(1, position);
                return invalid;
            }

            SetErrorStatus(0, position);
            return string.Empty;

        };

The compiler defines the validate(...) func as static. Why?

TIA

Alan Wayne
  • 5,122
  • 10
  • 52
  • 95
  • 1
    `validate` lambda does not use `this`, so no reason to generate instance method for than anonymous method. – user4003407 Sep 19 '15 at 04:00
  • @PetSerAl Could func<> validate be forced to be non-static? – Alan Wayne Sep 19 '15 at 04:03
  • 1
    What the point of making backing method of delegate non-static? You can always write method by yourself and create delegate from it. By the way, as you can not refer to `this` in field initializer, you can not create delegate from non-static method of current instance in field initializer, it have to be done in the constructor. – user4003407 Sep 19 '15 at 04:31
  • @PetSerAl Initialy, when using the func<> validate within the initializer, it was forcing me to make static all references from within the func... leading to making instance properites static as well...which I did not want to do. :) Thanks. – Alan Wayne Sep 19 '15 at 04:43
  • 1
    So, you have to initialize `validate` field in the constructor instead of field initializer. – user4003407 Sep 19 '15 at 04:59

2 Answers2

1

In that case, validate is not a method but a field. The field is an instance member. The object assigned to that field is a delegate that refers to an anonymous method. There's no reason for that method to be an instance member because it doesn't make any reference to the current instance. So, you have an instance field referring to a static method.

jmcilhinney
  • 50,448
  • 5
  • 26
  • 46
  • Could func<> validate be made non-static? Thanks. – Alan Wayne Sep 19 '15 at 04:11
  • @jmcilhinney Good answer, may I know if this is just concept knowledge of C# for you or you learnt it from a hard way too ? Like Alan, I didn't even notice about this until today. You made me start questioning about myself. – cscmh99 Sep 19 '15 at 04:42
  • 1
    *There's no reason for that method to be an instance member because it doesn't make any reference to the current instance.* Says who? That is an implementation detail of the compiler, which has changed BTW. – Yuval Itzchakov Sep 19 '15 at 08:02
  • Really ? all of you did pay attention down to the implementation level ? God .... I really need to change my attitude of learning things. – cscmh99 Sep 19 '15 at 13:09
1

The fact that the compiler generates a static method on the calling class instead of an instance one is an implementation detail of the compiler, which is subject to change, and actually has changed with the release of Roslyn. You can see Delegate caching behavior changes in Roslyn and see that now, the compiler generates a display class even for non capturing delegates.

I don't see though how this has to do with declaring anything as static inside your class.

Community
  • 1
  • 1
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321