通用方法和无效的上下文异常

时间:2013-06-13 23:46:03

标签: c# .net generics enums

我正在尝试编写自定义授权服务,我在其中注册模块以检查表示可用活动的特定枚举的权限:

public interface IAuthorizationService
{
    void Register<T>(IAuthorizationModule module);
    bool Authorize<T>(T activity);
}

public class AuthorizationService : IAuthorizationService
{
    private readonly Dictionary<Type, IAuthorizationModule> activities;

    public AuthorizationService()
    {
        activities = new Dictionary<Type, IAuthorizationModule>();
    }

    public void Register<T>(IAuthorizationModule module)
    {
        activities[typeof(T)] = module;
    }

    public bool Authorize<T>(T activity)
    {
        return activities[typeof(T)].Authorize(activity);
    }
}
public interface IAuthorizationModule
{
    bool Authorize<T>(T activity);
}

public class OrderAuthModule : IAuthorizationModule
{
    public bool Authorize<OrderActivity>(OrderActivity activity)
    {
        return activity == OrderActivity.Cancel;
    }
}

public enum OrderActivity
{
    Place,
    Cancel,
    Refund
}

此代码无法编译,但出现以下异常:

'OrderActivity' is a 'type parameter', which is not valid in the given context

在线:return activity == OrderActivity.Cancel;

我无法将接口声明为IAuthorizationModule<T>,因为我需要一个<Type, IAuthorizationModule>字典来注册将响应类型T(枚举)的模块。

我在这里缺少什么?

3 个答案:

答案 0 :(得分:2)

嗯,你的设计听起来不对我说。从您的具体类和AuthorizeService的实现,我假设每个IAuthorizationModule应该只负责一种类型的活动。如果我是对的,那么界面应该声明为

public interface IAuthorizationModule<T>
{
    bool Authorize(T activity);
}

public class OrderAuthModule : IAuthorizationModule<OrderActivity>
{
    public bool Authorize<OrderActivity>(OrderActivity activity)
    {
        return activity == OrderActivity.Cancel;
    }
}

您还需要相应地修改AuthorizationService

public class AuthorizationService : IAuthorizationService
{
    private readonly Dictionary<Type, object> activities;

    public AuthorizationService()
    {
        activities = new Dictionary<Type, object>();
    }

    public void Register<T>(IAuthorizationModule<T> module)
    {
        activities[typeof(T)] = module;
    }

    public bool Authorize<T>(T activity)
    {
        return ((IAuthorizationModule<T>)activities[typeof(T)]).Authorize(activity);
    }
}

这样可以更轻松地实现每个IAuthorizationModule

答案 1 :(得分:2)

Authorize更新为<T>可能会解决问题..

public class OrderAuthModule : IAuthorizationModule
{
    public bool Authorize<T>(T activity)
    {
        return activity.ToString() == OrderActivity.Cancel.ToString();
    }
}

<强>用法:

        var authorization = new AuthorizationService();

        var orderMod = new OrderAuthModule();

        authorization.Register<OrderActivity>(orderMod);

        var status = authorization.Authorize(OrderActivity.Place);

希望,我没有弄错语境......

对于记录:

您可以使用结构约束将泛型类型参数约束为值类型(例如int,bool和enum)或任何自定义结构:Ref

public class MyClass<T> where T : struct 

{...}

答案 2 :(得分:1)

请试试这个luiz

编辑:

public bool Authorize<T>(T activity)
        {
            return activity.Equals(OrderActivity.Cancel);
        }

编辑:  做切换语句试试这个luiz

OrderActivity act = (OrderActivity)Enum.Parse(typeof(OrderActivity), activity.ToString());
            switch (act)
            {
                case OrderActivity.Place:
                    return true;
                    break;
                case OrderActivity.Cancel:
                    return false;
                    break;
                default:
                    return default(bool);
            }

重要的是switch()上面的行,你将活动变量解析为enum变量并将其放入开关中,希望它有帮助...... 1)我们检查T上的相等性(占位符)在我的情况下没有设置任何东西)和枚举值,在你的情况下是异常(使用类型(T))2)它没有工作,因为我们处理T没有定义为任何特定的,并且swtch操作我的编辑中的bool,string,char,int,enum或相应的可空类型和活动是T,很高兴我能帮忙:))