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

其中func2, func3,func4确实需要对 someObject 的引用。我想将其更改为

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 中使用它。换句话说,这就像为特定代码块设置一些上下文对象。为此,我可以使用三种语言(C#、F# 或 IronPython)中的任何一种。

更新在理想的解决方案中,B 类将独立于 A。func*函数仅依赖于 A 的一个由 2 个方法组成的小接口。

UPDATE2 someObject 对于不同的函数调用可能不同。

UPDATE3我不认为只有使用类、接口或扩展方法等语言原语才能做到这一点。我认为解决方案可能会使用更多的 hackish 工具,例如属性、反射或 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 返回一些东西,那么你需要使用 Func<> 而不是 Action<>

或者,根据我在下面的评论,扩展方法也可能是一种选择。

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

}

// caller
someObject.Func2(5);

另一个选项可能是 F# 中的管道运算符。我有基本的 F# 知识,但我认为您可以定义一个具有两个参数的函数并使用管道运算符填充第一个参数的值。所以像:

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

可以调用

4 |> printnums 5;;

哪个输出:

4 - 5

使用 func2 你会有类似的东西

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

更多示例:stackoverflow:管道 F# 参数

我希望这有帮助!

于 2012-11-23T22:37:30.903 回答
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
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

如果所有这些函数都在一个对象(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 回答