2010-08-02 3 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, оно не дает вам доступа к конструкторам, только статическим членам. Вам нужно будет реализовать TryInvoke в классе StaticMembersDynamicWrapper, чтобы использовать этот тип в качестве конструктора. Добавьте это к классу:

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

It's неудовлетворительного на коде код если { динамического newObject = typeDynamic (проект, item.Name) (String.IsNullOrEmpty (item.Name)!); новыйObject.Save(); } – learning

2

Это, вероятно, было бы намного проще, объявив интерфейс, предоставляющий все общие свойства и методы, необходимые, а затем просто реализовать интерфейс для каждого класса и записать совместно используемый код для работы с интерфейсом.

Смежные вопросы