2010-08-02 60 views
1

我試圖使用示例表單http://blogs.msdn.com/b/davidebb/archive/2009/10/23/using-c-dynamic-to-call-static-members.aspx來消除代碼重複。如何使用動態刪除重複代碼

if (Categories != null) { 
     foreach (var item in Categories) 
     { 
      if (item.ID != 0) 
      { 
       Category category = Category.Load(item.ID); 
       category.Name = item.Name; 
       category.Project = project; 
       category.Save(); 
      } 
      else 
      { 
       if(!String.IsNullOrEmpty(item.Name)) 
       { 
        Category category = new Category(project, item.Name); 
        category.Save(); 
       } 
      } 
     } 
} 


      if (Priorities != null) 
      { 
       foreach (var item in Priorities) 
       { 
        if (item.ID != 0) 
        { 
         Priority priority = Priority.Load(item.ID); 
         priority.Name = item.Name; 
         priority.Project = project; 
         priority.Save(); 
        } 
        else 
        { 
         if (!String.IsNullOrEmpty(item.Name)) 
         { 
          Priority priority = new Priority(project, item.Name); 
          priority.Save(); 
         } 
        } 
       } 

我試圖做一些事情如下,但有錯誤消息

在部分不能調用非委託類型

if (!String.IsNullOrEmpty(item.Name)) 
       { 
        dynamic newObject = typeDynamic(project, item.Name); 
        newObject.Save(); 
       } 

SaveObjects(typeof(Category), Categories.ToList(), project); 
SaveObjects(typeof(Priority), Priorities.ToList(), project); 

任何幫助請。

謝謝。

什麼是錯,我該如何糾正?

private void SaveObjects(Type type, dynamic currentItems, Project project) 
    { 
     dynamic typeDynamic = new StaticMembersDynamicWrapper(type); 
     foreach (var item in currentItems) 
     { 
      if (item.ID != 0) 
      { 
       dynamic classValues = typeDynamic.Load(item.ID); 
       classValues.Name = item.Name; 
       classValues.Project = project; 
       classValues.Save(); 

      } 
      else 
      { 
       if (!String.IsNullOrEmpty(item.Name)) 
       { 
        dynamic newObject = typeDynamic(project, item.Name); 
        newObject.Save(); 
       } 
      } 
     } 

    } 

回答

0

您已經定義typeDynamic是一個動態的類型,但後來嘗試使用它作爲實際類型(使用它作爲一個構造typeDynamic(...))。這不是他們打算如何使用,只是使用點(typeDynamic.someMember)訪問成員。通過使用StaticMembersDynamicWrapper閱讀,它不會讓您訪問構造函數,只有靜態成員。您需要在StaticMembersDynamicWrapper類中實現TryInvoke以將該類型用作構造函數。添加到課程:

public override bool TryInvoke(InvokeBinder binder, object[] args, out object result) 
{ 
    ConstructorInfo ctor = _type.GetConstructor(args.Select(arg => arg.GetType()).ToArray()); 
    if (ctor == null) 
    { 
     result = null; 
     return false; 
    } 

    result = ctor.Invoke(args); 
    return true; 
} 

不是非常強大,但應該爲你工作足夠。不過,我強烈建議使用ck或其他非動態方法建議的更簡單的方法。


不同的(非動態)的方式,你可以採取的使用委託給你的靜態功能。請參閱我在此問題中的回答,Curious problem involving generics and static methods

+0

它'的代碼錯誤的代碼 如果 { 動態NEWOBJECT = typeDynamic(項目,item.Name)(String.IsNullOrEmpty(item.Name)!); newObject.Save(); } – learning 2010-08-02 07:54:53

2

通過聲明一個暴露所有需要的共享屬性和方法的接口,然後爲每個類實現接口,並編寫共享代碼以在接口上工作,這可能會容易得多。