2012-11-23 32 views
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); 
} 

func2func3func4确实需要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)中的任何一种。

UPDATE在理想的解决方案中,B类将独立于A. func*函数仅依赖于包含2个方法的A的小接口。

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

UPDATE3我不认为有一种方法只能用类,接口或扩展方法等语言基元来完成此操作。我认为解决方案可能会使用更多的黑客工具,例如属性,反射或F#的计算工作流程特性。或者可能是IronPython的一些动态功能。基本上我想要做的是创建一个小型嵌入式DSL。

+1

听起来像你正在寻找一个全局变量? – Cameron

+1

除了上述两个注释/选项之外,也许您可​​以使用诸如部分函数应用程序或柯里格之类的东西:http://msmvps.com/blogs/jon_skeet/archive/2012/01/30/currying-vs-partial-function -application.aspx –

+0

@rid'func *'已经是另一个类的方法了。理想情况下,someObject和'func *'类应该是彼此独立的,所以我可以轻松地用另一个类替换someObject而不更改'func *的类 – Max

回答

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键<>而非行动<>

另外,如下面的扩展方法,我的意见可能是一种选择也。

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: Piping F# Parameters

我希望这有助于!

+0

谢谢。这是我在发布这个问题之前想要做的。但是代码太复杂了。我会很好,如果我没有写所有'var func2Partial = new Action ((i)=> func2(objectInstance,i));' – Max

+1

如何在类型上做func2,func3和func4扩展方法someObject的?调用代码然后会变成someObject.func2(5),但你不需要代表? – BrianB

+0

正如我在另一条评论中写的,我希望'func *'独立于someObject的类型。 – Max

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(); 
+0

谢谢,但对象是不一样的。此外,我希望'func *'与someObject的类型正交 – Max

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

你可以写一个函数,它接受一个A和返回FUNC2功能。 例如,如果FUNC2返回类型为void(如果没有,则使用函数功能< INT,返回类型>):

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

然后,徘徊无论适合,可以声明

var func2=func2Gen(someObject); 

并调用它:

func2(1);