0

私の意図をコードで説明する方が良いです。だから今、私は次のコードを持っています:

class A, IInterfaceUsedByB
{
}

class B
{
    void func(A someObject)
    {
        func2(someObject, 1);
        func3(someObject, "string");
        func4(someObject, new MyObject());

        var anotherObject = someObject.NewInstance;
        func2(anotherObject, 1);
        .......................
    }
    func2(A someObject, int val);
    func3(A someObject, string val);
    func4(A someObject, C val);
}

func2func3、someObjectfunc4への参照が必要な場所。これを次のように変更したい

void func(A someObject)
{
    with(someObject,
            () =>
                {
                    func2(1);
                    func3("string");
                    func4(new MyObject());
                }
        );
    var anotherObject = someObject.NewInstance;
    with(anotherObject,
            () =>
                {
                    func2(1);
                    .......................
                }
        );
}

またはさらに良い

void func(A someObject)
{
    func2(1);
    func3("string");
    func4(new MyObject());
}

この someObject をドラッグする必要はありませんが、func2,3,4 内で使用できるはずです。つまり、特定のコード ブロックにコンテキスト オブジェクトを設定するようなものです。これには、3 つの言語 (C#、F#、または IronPython) のいずれかを使用できます。

更新理想的なソリューションでは、クラス B は A から独立しています。func*関数は、2 つのメソッドで構成される A の小さなインターフェイスにのみ依存します。

UPDATE2 someObjectは、関数呼び出しごとに異なる場合があります。

UPDATE3クラス、インターフェース、拡張メソッドなどの言語プリミティブのみでこれを行う方法はないと思います。属性、リフレクション、F# の計算ワークフロー機能など、よりハックなツールを使用して解決できる可能性があると思います。あるいは、IronPython のいくつかの動的機能かもしれません。基本的に、私がやろうとしているのは、小さな組み込み DSL を作成することです。

4

4 に答える 4

1

ここでは、部分機能アプリケーションが機能する可能性があります。

// object for example first param
var objectInstance = new object();

// partial function application
var func2Partial = new Action<int>((i) => func2(objectInstance, i));
func2Partial(5);

func2が何かを返す場合は、Action<>ではなくFunc<>を使用する必要があります。

あるいは、以下の私のコメントによると、拡張メソッドもオプションである可能性があります。

internal static class IInterfaceUsedByBExtender
{
    internal static void Func2(this IInterfaceUsedByB obj, int value)
    {
    }

}

// caller
someObject.Func2(5);

別のオプションは、F#のパイプ演算子です。私はv。基本的なF#の知識を持っていますが、2つのパラメーターを使用して関数を定義し、パイプ演算子を使用して最初のパラメーターの値を入力できると思います。だから次のようなもの:

let printnums x y = printfn "%A - %A" x y;;

によって呼び出すことができます

4 |> printnums 5;;

どの出力:

4 - 5

func2を使用すると、次のようなものになります

let func2 obj, num = ...;
someObject |> func2 1;;

このその他の例:stackoverflow:Piping F#パラメーター

これがお役に立てば幸いです。

于 2012-11-23T22:37:30.903 に答える
0
class A, IInterfaceUsedByB
{ 
}

class B<T> where T : A
{
    private T m_SomeObject;

    public B(T someobject)
    {
        m_Someobject = someobject;
    }
    void func()
    {
        func2(1);
        func3("string");
        func4(new MyObject());
    }
    func2(int val) { //Do whatever with m_SomeObject }
    func3(string val) { //Do whatever with m_SomeObject }
    func4(C val){ //Do whatever with m_SomeObject }
}
于 2012-11-23T23:08:21.477 に答える
0

A を受け取って func2 関数を返す関数を作成できます。たとえば、func2 の戻り値の型が void の場合 (そうでない場合は、Func < int, ReturnType> を使用します):

        Action<int> func2Gen(A someObject)
        {
           return i => Console.WriteLine(i+someObject.ToString());
        }

次に、適切な場所で宣言できます

var func2=func2Gen(someObject);

そしてそれを呼び出します:

func2(1);
于 2012-12-03T12:32:32.290 に答える
0

これらすべての関数が 1 つのオブジェクト (sameObject) に対して動作する場合は、クラスを導入してクラス メソッドにする必要があるようです。someObject の型はわかりませんが、C# の例を次に示します。

class Workflow<T>
    where T: class
{
    private readonly T _someObject;

    public Workflow(T someObject)
    {
        _someObject = someObject;
    }


    public void func() 
    {
         func2(1);
         func3("string");
         func4(new MyObject());
    } 

    private void func2(int a) 
    {
        // use _someObject here
    }

    private void func3(string s) 
    {
        // ...
    }
}

// usage
var flow = new Workflow(someObject);
flow.f();
于 2012-11-23T23:01:47.790 に答える