最好的方式来动态地创建类,而不是使用一个开关块 [英] Best way to dynamically create classes instead of using a switch block

查看:138
本文介绍了最好的方式来动态地创建类,而不是使用一个开关块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我已经在实现接口的类来实现我的VaryByCustom是功能 IOutputCacheVaryByCustom

Currently I have my VaryByCustom functionality implemented in classes that implement an interface IOutputCacheVaryByCustom

public interface IOutputCacheVaryByCustom
{
    string CacheKey { get; }
    HttpContext Context { get; }
}

一个类实现这个接口有一些约定类的名称会是OutputCacheVaryBy_的 __ 里的空白是从VaryByCustom是属性传递页面上的价值。另一个约定是这方面将通过构造器注入来设定。

A class implementing this interface has a few conventions the name of the class will be "OutputCacheVaryBy___" where the blank is the value that is passed in from the varyByCustom property on pages. The other convention is that Context will be set through constructor injection.

目前,我立足这一关枚举和类似于

Currently I'm basing this off an enum and a switch statement similar to

public override string GetVaryByCustomString(HttpContext context, 
                                              string varyByCustomTypeArg)
{
    //for a POST request (postback) force to return back a non cached output
    if (context.Request.RequestType.Equals("POST"))
    {
        return "post" + DateTime.Now.Ticks;
    }
    var varyByCustomType = EnumerationParser.Parse<VaryByCustomType?>
                            (varyByCustomTypeArg).GetValueOrDefault();


    IOutputCacheVaryByCustom varyByCustom;
    switch (varyByCustomType)
    {
        case VaryByCustomType.IsAuthenticated:
            varyByCustom = new OutputCacheVaryByIsAuthenticated(context);
            break;
        case VaryByCustomType.Roles:
            varyByCustom = new OutputCacheVaryByRoles(context);
            break;
        default:
            throw new ArgumentOutOfRangeException("varyByCustomTypeArg");
    }

    return context.Request.Url.Scheme + varyByCustom.CacheKey;
}



因为我总是知道类将是 OutputCacheVaryBy + varyByCustomTypeArg 和唯一的构造函数参数将是背景我意识到我可以绕过需要这个荣耀的if else块可能只是实例我自己的目标与激活

Since I always know that the class will be OutputCacheVaryBy + varyByCustomTypeArg and the only constructor argument will be context I realized I could bypass needing this glorified if else block and could just instantiate my own object with Activator.

通过这个虽这么说,反思是不是我的强项,我知道,激活基本相对缓慢静态创作和其他方法来生成对象。是否有任何理由为什么我要这个当前的代码坚持还是应该使用激活或类似的方法来创建我的对象?

With this being said, reflection is not my strong suit and I know that Activator is substantially slow comparatively to static creation and other ways to generate objects. Is there any reason why I should stick with this current code or should I use Activator or a similar way to create my object?

我已经看到了博客的 http://www.smelser.net/blog/post/2010/03/05/When-Activator-is-just-to-slow.aspx ,但我真的不知道如何做到这一点适用,因为我与类型在运行时不静牛逼的工作。

I've seen the blog http://www.smelser.net/blog/post/2010/03/05/When-Activator-is-just-to-slow.aspx but I'm not really sure how this would apply since I'm working with types at runtime not static T.

推荐答案

您并不需要使用反射,因为它是一组相当有限的可能值。然而,你可以做这样的事情。

You don't really need to use reflection since it's a rather limited set of possible values. You could however do something like this

internal class Factory<T,Arg>
{
   Dictionary<string,Func<Arg.T>> _creators;
   public Factory(IDictionary<string,Func<Arg,T>> creators)
  {
     _creators = creators;
  }
}



and substitute your creation logic with

_factory[varyByCustomTypeArg](context);



这不是一样快的开关,但会将建设和使用很好地单独

it's not as fast as a switch but it keeps construction and use nicely seperate

这篇关于最好的方式来动态地创建类,而不是使用一个开关块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆