2009-09-17 3 views
1

Est-il possible d'appeler une méthode sur un objet retourné à l'aide de l'opérateur infixe de pipeline? Exemple, j'ai une classe .Net (Class1) avec une méthode (Méthode 1). Je peux le code actuellement comme ceci:Est-il possible d'utiliser l'opérateur de pipeline pour appeler une méthode sur un objet retourné?

let myclass = new Class1() 
let val = myclass.Method1() 

Je sais que je pourrais coder aussi en tant que tel

let val = new Class1().Method1() 

Cependant, je voudrais faire être en mesure de pipeline (je me sers du dessous où? Je ne sais pas quoi faire):

new Class1() 
|> ?.Method1() 

de plus, dire que j'avais une méthode qui retourne un objet, et je veux faire référence uniquement si cette méthode n'a pas retourné nul (sinon caution)

?
new Class1() 
|> ?.Method1() 
|> ?? ?.Method2() 

Ou pour le rendre plus clair, voici un code C#:

public void foo() 
    { 
     var myclass = new Class1(); 
     Class2 class2 = myclass.Method1(); 
     if (class2 == null) 
     { 
      return; 
     } 
     class2.Method2(); 
    } 

Répondre

2

Vous pouvez définir quelque chose de similaire à votre opérateur (??) assez facilement (mais les opérateurs ne peuvent pas commencer par un point d'interrogation):

let (~??) f x = 
    if (x <> null) then 
    f x 

Malheureusement, votre code devra pipelinée être un peu plus bavard (aussi, notez que vous pouvez laisser tomber le mot-clé new pour appeler les constructeurs):

Class1() 
|> fun x -> x.Method1() 

Mettre le tout ensemble:

Class1() 
|> fun x -> x.Method1() 
|> ~?? (fun x -> x.Method2()) 
1

l'aide d'un opérateur personnalisé comme 'KVB' suggère est certainement une option. Une autre approche que vous pouvez trouver intéressante dans ce cas est de définir votre propre 'expression de calcul' qui effectue automatiquement la vérification de la valeur null à chaque point que vous spécifiez. Le code qui l'utilise ressemblerait à ceci:

open System.Windows.Forms 

// this function returns (0) null, or (1) btn whose parent is 
// null or (2) button whose parent is not null 
let test = function 
    | 1 -> new Button(Text = "Button") 
    | 2 -> new Button(Text = "Button", Parent = new Button(Text = "Parent")) 
    | _ -> null 

let res = 
    safe { let! btn = test(2) // specify number here for testing 
     // if btn = null, this part of the computation will not execute 
     // and the computation expression immediately returns null 
     printfn "Text = %s" btn.Text 
     let! parent = btn.Parent // safe access to parent 
     printfn "Parent = %s" parent.Text // will never be null! 
     return parent } 

Comme vous pouvez le voir, si vous souhaitez utiliser une valeur qui peut potentiellement être « nul », vous utilisez let! dans l'expression de calcul. L'expression de calcul peut être définie de sorte qu'elle renvoie immédiatement null si la valeur est null et exécute le reste du calcul dans le cas contraire. Voici le code:

type SafeNullBuilder() = 
    member x.Return(v) = v 
    member x.Bind(v, f) = 
    if v = null then null else f(v) 

let safe = new SafeNullBuilder()  

BTW: Si vous voulez en savoir plus à ce sujet, il est très similaire à « Peut-être » monade dans Haskell (ou calcul travaillant avec F # type d'option).

Questions connexes