0

Consider the code below:

public class Analyzer {
        protected Func f,fd;
        public delegate double Func( double x );
        public Analyzer( Func f, Func fd ) {
            this.f = f;
            this.fd = fd;
        }
        public Analyzer( Func f ) {
            this.f = f;
            fd = dx;
        }
        public Analyzer( ) { }
        protected double dx( double x ) {
            double h = x / 50.0;
            return ((f(x + h) - f(x - h)) / (2 * h)); 
        }
        public double evaluate(double x) {
            return f( x );
        }
        public double evaluateDerived( double x ) {
            return fd( x );
        }
        public double solve(double x0) {
            double eps = 1, x1 = f(x0), x2 = fd(x0);
            do x0 = x0 - ( f( x0 ) / fd( x0 ) );
            while ( f( x0 ) > eps );
            return x0;
        }
    }
    public class PolyAnalyzer : Analyzer {
        private double[] coefs;
        public PolyAnalyzer( params double[] coef ) {
            coefs = coef;
            f = poly;
            fd = dx;
        }
        private double poly( double x ) {
            double sum = 0;
            for ( int i = 0 ; i < coefs.Length ; i++ ) {
                sum += coefs[i] * Math.Pow(x,coefs.Length-1-i);
            }
            return sum;
        }
    }

I was trying to think of a way to send poly to the constructor Analyser(Func f), is there a way to do that here? tried something like :

public PolyAnalyzer( params double[] coef ) : base(new Func(poly)){
            coefs = coef;
        }

but it doesnt compile... compilation error:: An object reference is required for the nonstatic field, method, or property 'member'

Id appriciate a well explained answer, and not just how its done... :)

4
  • 1
    On a side note - I'd recommend using the framework's Func<double,double> delegate instead of defining your own. If you really want your own, give it a name other than Func to not confuse it with the BCL "Func" delegates... Commented Jul 6, 2012 at 17:15
  • Mmmm... the error itself will tell you that poly is a non-static member, if you make it static it will compile... but you should think this idea a little more, I don't see any sense on doing that, maybe if you describe what you need to accomplish we can help you. Commented Jul 6, 2012 at 17:23
  • the guidelines in the exercise were to use the base class constructor if possible, so i war trying to do so... if i declare poly static then then coef needs to be static, which is wrong because every instance should have its own coefs... Commented Jul 6, 2012 at 17:27
  • "the guidelines in the exercise" - if this is homework, please tag it as such. In that case, do whatever the instructor appears to be expecting. Commented Jul 6, 2012 at 17:50

2 Answers 2

1

The error you're getting:

An object reference is required for the non-static field, method, or property...

is due to the fact that poly is a member the object that you are creating, it is dependant upon the variables within the PolyAnalyzer class.

Normally you could resolve this by adding an object reference like it calls for (i.e. new Func(this.poly)) however the current instance of the class (this) isn't available within the context yet. (Your instance is not yet fully realized).

You can, like you have already done in your PolyAnalyzer constructor, set the values yourself, which would be my suggestion.

Sign up to request clarification or add additional context in comments.

Comments

0

In my opinion you're trying to combine object-oriented inheritance and functional programming, and it's not working well in this case.

I would write

public abstract class Analyzer {
    protected abstract double Fd(double x);
    // ...
}

and override it in the descendant class (if you want to stick with an OO hierarchy). This is classic Strategy Pattern implementation.

To address your comment, if you want Analyzer to be instantiable, use:

public class Analyzer {
    protected virtual double Fd(double x)
    {
        // provide default implementation
    }
    // ...
}

If you want to stick to functional programming, I would use composition instead of inheritance:

// Does not descend from Analyzer. Could implement IAnalyzer.
public class PolyAnalyzer {
    private readonly Analyzer analyzer;
    private double[] coefs;

    public PolyAnalyzer( params double[] coef ) {
        coefs = coef;

        analyzer = new Analyzer(poly);
    }

    public double evaluate(double x) {
        return analyzer.evaluate(x);
    }

    // Implement evaluateDerived and solve through delegation

    private double poly( double x ) {
        double sum = 0;
        for ( int i = 0 ; i < coefs.Length ; i++ ) {
            sum += coefs[i] * Math.Pow(x,coefs.Length-1-i);
        }
        return sum;
    }
}

Alternately, if you took @Reed Copsey's advice and switched to Func<double, double>, you could use closures in a factory method:

public static class PolyAnalyzerFactory {
    public static Analyzer Create( params double[] coef ) {
        var coefs = coef.ToArray();  // protect against mutations to original array

        return new Analyzer(
            x =>
            {
                double sum = 0;
                for ( int i = 0 ; i < coefs.Length ; i++ ) {
                    sum += coefs[i] * Math.Pow(x,coefs.Length-1-i);
                }
                return sum;
            });
    }
}

3 Comments

but Analyzer should be instantiable
i didnt get you yet, what do we profit from this approach? maybe add all the changes you make to the whole code... btw have you noticed that the function f' can be either given as a parameter or be set to the default f' proximity?
Please see my edit. While it's useful to combine the functional and OO paradigms, this is one case where they don't mesh well. Switching to composition will help. You may still need to change calling code if you need polymorphic behavior (adding an IAnalyzer interface).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.