集中行动计划

时间:2015-06-04 17:47:08

标签: c#

我有一个程序需要从各种表单执行一些操作。我想把行动放在一个集中的空间里。每个操作都有自己的类,该类派生自一个接口。

每个动作仅实例化一次,但用于各种场所,如上下文菜单,功能区,工具栏等。

我有以下代码工作,我想在制作列表时摆脱typeof。我希望有强烈的打字,没有反思和重构的可能性。

这可以更有效率吗?

class Program
    {
        static void Main(string[] args)
        {
            ActionManager actionManager = new ActionManager();

            List<SomeInterface> listA = actionManager.CreateList(typeof(Do_A), typeof(Do_B));
            List<SomeInterface> listB = actionManager.CreateList(typeof(Do_A), typeof(Do_B));
        }
    }

    public class ActionManager
    {
        private Dictionary<Type, SomeInterface> instantiatedActions = new Dictionary<Type, SomeInterface>();

        public List<SomeInterface> CreateList(params Type[] actions)
        {
            List<SomeInterface> theList = new List<SomeInterface>();

            foreach (Type type in actions)
            {
                if(!instantiatedActions.ContainsKey(type))
                {
                    instantiatedActions.Add(type, (SomeInterface)Activator.CreateInstance(type));
                }
                theList.Add(instantiatedActions[type]);
            }

            return theList;
        }
    }

    public interface SomeInterface
    {
    }

    public class Do_A : SomeInterface
    {
    }

    public class Do_B : SomeInterface
    {
    }

    public class Do_C : SomeInterface
    {
    }

1 个答案:

答案 0 :(得分:2)

如果尚未看到类型,您可以创建返回类型的表达式。这将允许您保持强类型,并强制只允许传入SomeInterface实现。

static void Main(string[] args)
{
    ActionManager actionManager = new ActionManager();

    List<SomeInterface> listA = actionManager.CreateList<SomeInterface>(
            () => new Do_A(), () => new Do_B());
    List<SomeInterface> listB = actionManager.CreateList<SomeInterface>(
            () => new Do_A(), () => new Do_B());
}

public class ActionManager
{
    private Dictionary<Type, SomeInterface> instantiatedActions = 
            new Dictionary<Type, SomeInterface>();

    public List<SomeInterface> CreateList<T>(params Expression<Func<T>>[] actions)
    {
        List<SomeInterface> theList = new List<SomeInterface>();

        foreach (var action in actions)
        {
            var type = GetObjectType<T>(action);
            if(!instantiatedActions.ContainsKey(type))
            {
                instantiatedActions.Add(type, (SomeInterface)action.Compile().Invoke());
            }
            theList.Add(instantiatedActions[type]);
        }

        return theList;
    }

    private static Type GetObjectType<T>(Expression<Func<T>> expr)
    {
        if ((expr.Body.NodeType == ExpressionType.Convert) ||
            (expr.Body.NodeType == ExpressionType.ConvertChecked))
        {
            var unary = expr.Body as UnaryExpression;
            if (unary != null)
                return unary.Operand.Type;
        }
        return expr.Body.Type;
    }
}

警告需要编译表达式以调用它并需要从表达式树返回类型。但是,根据您的评论,它仅在尚未看到类型时确保延迟实例化,并保证类型安全。