2016-08-02 36 views
5

Bir işlevi temel olarak kendisini temsilci olarak döndürecek şekilde tanımlamak mümkün mü?Bir işlev döndüren bir işlev döndürme işlevi, vb

public class Scrub 
{ 
    public NotNull NotNull<T>(T value, string name) 
    { 
     if (value == null) throw new ArgumentNullException(name); 
     return NotNull; 
    } 
} 

Sonra elimden zincir yöntemi birlikte böyle çağırır: Bu geçerli sözdizimi Söz gelimi

.

Scrub.NotNull(param1, nameof(param1))(param2, nameof(param2)(param3, nameof(param3)); 

cevap

14

Eh evet, , kendi temsilci bildirimi ile yapabilirsiniz:

delegate SelfReturner<T> SelfReturner<T>(T value, string name); 

static SelfReturner<T> NotNull<T>(T value, string name) 
{ 
    if (value == null) throw new ArgumentNullException(name); 
    return NotNull; 
} 

... ama benim için kullanışlı görünmüyor. Bunu yapmak için herhangi bir sebep, sadece üç ayrı çağrı yapmaktan ibaret değil? Örneğin, null olmayan bir değeri döndüren Preconditions.CheckNotNull'um var - dürüst olmak gerekirse, bu görünümden çok daha kullanışlı olduğunu düşünüyorum.

Açıklamalarda belirtildiği gibi, yukarıdakiler yalnızca tüm parametreler aynı tipte (veya tümüyle birinci parametrenin türüne tamamen dönüştürülebilir) çalışıyorsa çalışır. iki farklı yöntem, bir statik ve bir ile

NullChecker.Instance.Scrub(param1, nameof(param1)) 
        .Scrub(param2, nameof(param2)) 
        .Scrub(param3, nameof(param3)); 

:

public sealed class NullChecker 
{ 
    public static NullChecker Instance { get; } = new NullChecker(); 
    private NullChecker() {} 

    public static NullChecker Scrub<T>(T value, string paramName) where T : class 
    { 
     if (value == null) 
     { 
      throw new ArgumentNullException(paramName); 
     } 
     return this; 
    } 
} 

Kullanımı için: bir alternatif genel bir yöntem ile bir tekil örneği kullanmak olacaktır bir biraz daha fazla çalışma ile zincir izin vermek için (ancak farklı isimlerle) Instance bölümünü kaldırabilirsiniz. Örneğin:

public static class Scrub 
{ 
    public static T NotNull<T, U>(this T value, U property, string name) 
    { 
     if (property == null) throw new ArgumentNullException(name); 
     return value; 
    } 
} 

Sen yapabilirsin:

test.NotNull(test.A, nameof(testA.A).NotNull(test.B, nameof(testA.B))); 

istediğini değil tamamen ne

NullChecker.Scrub(param1, nameof(param1)) 
      .And(param2, nameof(param2)) 
      .And(param3, nameof(param3)); 
+0

Ama eğer 'param1' bir dizgeyse, bu sadece 'param2', 'param3', ... dizeleri olsaydı işe yarardı, değil mi? –

+0

Gerçekten sadece her şeyden çok mümkün olsaydı merak ettim. – adam0101

+1

@IanMercer: Ah evet, haklısın. Bunu düzeltmenin kolay olduğundan emin değilim - muhtemelen tek bir metodun olması daha iyi olur. Bunu belirtecek şekilde düzenler. –

1

bunu bir uzantısı yöntemi yaparsanız.

İlgili konular