2012-06-29 42 views
3

一如既往,幫助/評論的想法總是值得讚賞的,我的編程天真的appologies。c#和LINQ其中收集成員的屬性名稱通過函數傳遞

我想創建一個廣泛適用的函數,可以用於未來的研究,涉及塊隨機化。 patientDataCollection的每個成員都會有一個名爲interventionArm,givenDrugX或類似名稱的布爾屬性。該功能旨在(隨機)隨機分配到研究的一個分支,取決於分塊大小 - 也就是說,如果分塊大小爲8,4分配給治療,4分配給控制(不處理)。

到目前爲止的代碼:

public static bool nextAllocation<T>(int blockSize, IEnumerable<T> patientDataCollection, string allocationPropertyName) 
{ 
    int remainingAllocations = blockSize - patientDataCollection.Count(); 
    if (remainingAllocations <= 0) throw new Exception("All alocations within block accounted for"); 
    var p = typeof(T).GetProperty(allocationPropertyName); 

    int remainingInterventions = blockSize/2 - patientDataCollection.Count(c => c.p); 
    double Pintervention = (double)remainingInterventions/(double)remainingAllocations; 
    double rdm = new Random().NextDouble(); 
    return (rdm <= Pintervention); 
} 

這當然有缺陷的邏輯的,因爲變量p不涉及在LINQ語句patientDataCollection.Count到c.p引用(C => c.p)。顯然這個陳述僅僅是計算所有具有真實價值的元素。

ASP是4.0。任何人都可以看到如何實現這一

回答

1

您可以使用reflection來獲得屬性的值:

int remainingInterventions = blockSize/2 - 
    patientDataCollection.Count(c => (bool)p.GetValue(c,null)); 

添加錯誤檢查爲好。

0

嘗試使用表達式

public static class ExpressionCreator 
{ 
    public static Func<T, TProperty> CreatePropertyAccessExpression<T, TProperty>(string propertyName) 
    { 
     var tType = typeof (T); 
     var property = tType.GetProperty(propertyName); 
     var parameterExpression = Expression.Parameter(tType); 
     var memberAccessExpression = Expression.MakeMemberAccess(parameterExpression, property); 
     var lambda = Expression.Lambda<Func<T, TProperty>>(memberAccessExpression, parameterExpression); 
     return lambda.Compile(); 
    } 
} 

用法示例:

public class A 
    { 
     public bool Thing1 { get; set; } 
     public bool Thing2 { get; set; } 
    } 

    static void Main(string[] args) 
    { 
     var @as = new A[10]; 
     for(var i = 0; i < @as.Length; i+=2) 
     { 
      @as[i] = new A {Thing1 = true}; 
      @as[i + 1] = new A {Thing2 = i%4 == 0}; 
     } 

     var thing1Expression = ExpressionCreator.CreatePropertyAccessExpression<A, bool>("Thing1"); 
     var thing2Expression = ExpressionCreator.CreatePropertyAccessExpression<A, bool>("Thing2"); 
     Console.WriteLine(@as.Count(thing1Expression)); 
     Console.WriteLine(@as.Count(thing2Expression)); 
     Console.ReadLine(); 
    } 
2

您可以傳遞給你的方法,將用於計數一個Func<T, bool>

public static bool nextAllocation<T>(int blockSize, IEnumerable<T> patientDataCollection, Func<T,bool> predicate) 
{ 
    int remainingAllocations = blockSize - patientDataCollection.Count(); 
    if (remainingAllocations == 0) throw new Exception("All alocations within block accounted for"); 
    int remainingInterventions = blockSize/2 - patientDataCollection.Count(predicate); 
    double Pintervention = remainingInterventions/remainingAllocations; 
    double rdm = new Random().NextDouble(); 
    return (rdm <= Pintervention); 
} 

使用的一個例子是這樣的:

var result = nextAllocation(10, collection, c=>c.interventionArm);