0

以下のコードを検討してください。

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;
        }
    }

コンストラクターAnalyser(Func f)にpolyを送信する方法を考えようとしていましたが、ここでそれを行う方法はありますか?次のようなものを試しました:

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

ただし、コンパイルされません...コンパイルエラー::非静的フィールド、メソッド、またはプロパティ'member'にはオブジェクト参照が必要です

Idは、それがどのように行われたかだけでなく、よく説明された答えを評価します... :)

4

2 に答える 2

1

発生しているエラー:

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

PolyAnalyzerpolyは作成しているオブジェクトのメンバーであるため、クラス内の変数に依存します。

object reference通常、これを解決するには、(つまり)を呼び出すようなものを追加しnew Func(this.poly)ますが、クラス(this)の現在のインスタンスはまだコンテキスト内で使用できません。(インスタンスはまだ完全には実現されていません)。

コンストラクターですでに行ったように、PolyAnalyzer自分で値を設定することができます。これが私の提案です。

于 2012-07-06T17:26:44.720 に答える
0

私の意見では、オブジェクト指向の継承と関数型プログラミングを組み合わせようとしていますが、この場合はうまく機能していません。

私は書くだろう

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

子孫クラスでオーバーライドします(オブジェクト指向階層を維持したい場合)。これは古典的な戦略パターンの実装です。

コメントに対処するには、Analyzerをインスタンス化できるようにする場合は、次を使用します。

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

関数型プログラミングに固執したい場合は、継承の代わりに合成を使用します。

// 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;
    }
}

または、@ Reed Copseyのアドバイスを受けてに切り替えたFunc<double, double>場合は、ファクトリメソッドでクロージャを使用できます。

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;
            });
    }
}
于 2012-07-06T17:30:00.553 に答える