Как использовать динамический для устранения дубликата кода - PullRequest
1 голос
/ 02 августа 2010

Я попытался использовать пример формы 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();
                }
            }
        }

    }

Ответы [ 2 ]

2 голосов
/ 02 августа 2010

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

0 голосов
/ 02 августа 2010

Вы определили 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 или другим не динамическим подходом.


Другой (не динамический) подход, который вы можете использовать, - это использование делегатов для ваших статических функций. Обратитесь к моему ответу в этом вопросе Любопытная проблема с использованием обобщенных и статических методов .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...