Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 集中程序的操作_C# - Fatal编程技术网

C# 集中程序的操作

C# 集中程序的操作,c#,C#,我有一个程序,需要从各种形式执行一些操作。我想把动作放在一个集中的空间里。每个操作都有自己的类,该类派生自接口 每个动作只实例化一次,但在不同的位置使用,如上下文菜单、功能区、工具栏等 我有下面的代码在工作,我想在制作列表时去掉typeof in。我希望有强大的类型,没有反射和重构的可能性 这样做能更有效率吗 class Program { static void Main(string[] args) { ActionManage

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

每个动作只实例化一次,但在不同的位置使用,如上下文菜单、功能区、工具栏等

我有下面的代码在工作,我想在制作列表时去掉typeof in。我希望有强大的类型,没有反射和重构的可能性

这样做能更有效率吗

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
    {
    }
类程序
{
静态void Main(字符串[]参数)
{
ActionManager ActionManager=新建ActionManager();
List listA=actionManager.CreateList(typeof(Do_A),typeof(Do_B));
listListB=actionManager.CreateList(typeof(Do_A),typeof(Do_B));
}
}
公共类ActionManager
{
私有字典实例化操作=新建字典();
公共列表CreateList(参数类型[]操作)
{
列表列表=新列表();
foreach(操作中的类型)
{
如果(!InstancedActions.ContainsKey(类型))
{
添加(类型,(SomeInterface)Activator.CreateInstance(类型));
}
添加(实例化操作[type]);
}
返回列表;
}
}
公共接口
{
}
公共类Do_A:SomeInterface
{
}
公共类Do_B:SomeInterface
{
}
公共类Do_C: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;
    }
}
static void Main(字符串[]args)
{
ActionManager ActionManager=新建ActionManager();
List listA=actionManager.CreateList(
()=>新Do_A(),()=>新Do_B();
List listB=actionManager.CreateList(
()=>新Do_A(),()=>新Do_B();
}
公共类ActionManager
{
私有字典实例化操作=
新字典();
公共列表CreateList(参数表达式[]操作)
{
列表列表=新列表();
foreach(行动中的var行动)
{
变量类型=GetObjectType(操作);
如果(!InstancedActions.ContainsKey(类型))
{
instancedActions.Add(type,(SomeInterface)action.Compile().Invoke());
}
添加(实例化操作[type]);
}
返回列表;
}
私有静态类型GetObjectType(表达式expr)
{
if((expr.Body.NodeType==ExpressionType.Convert)||
(expr.Body.NodeType==ExpressionType.ConvertChecked))
{
变量一元=将主体表示为一元表达式;
if(一元!=null)
返回一元数.Operand.Type;
}
返回expr.Body.Type;
}
}

警告是需要编译表达式以调用它,并且需要从表达式树返回类型。然而,根据您的评论,只有在尚未看到类型的情况下,它才能确保延迟实例化,并保证类型安全。

此外,
SomeInterface
Do_A/B/C
类不太可能在CR上飞过。假设的示例代码不适合代码审查。这看起来非常像命令模式,我建议阅读WPF如何使用命令。我不确定您使用的是什么UI,但值得一看:@Ron Beyer:ICommand确实是SomeInterface的一部分:)但其中还有很多东西。Glyphs、Displaynames等。我试图实现的有点像DevExpress的BarManager,其中程序的所有操作都保存在一个中心位置。非常漂亮的解决方案。调用列表看起来有点难看,但它实现了我的要求。我不会将语法称为pretty:)。但它确实提供了强大的类型化和惰性实例化,并且语法也不会比您最初使用的语法更为详细。我的副作用似乎是,各种类的构造函数都可以使用参数。“我喜欢它:”@ JvdBerg是一个独特的优势,因为如果你从IOC内核调用这一点,你可以非常具体地描述你的对象是如何创建的,以及确切的依赖关系,我认为这是一个很好的DI例子。