繁体   English   中英

C#Type参数为通用声明

[英]C# Type parameter as Generic declaration

我在为泛型方法指定Type时尝试使用Type参数时收到错误。

错误:'JsonFilter.JsonDataType'是'属性',但用作'类型'

public class JsonFilter : ActionFilterAttribute
{
    public Type JsonDataType { get; set; }
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        ...
        JavaScriptSerializer jss = new JavaScriptSerializer();
        var result = jss.Deserialize<JsonDataType>(inputContent);//Error here
        ...

新规范

...
JavaScriptSerializer jss = new JavaScriptSerializer();
MethodInfo method = jss.GetType()
               .GetMethod("Deserialize")
               .MakeGenericMethod(new Type[] { JsonDataType });
var result = method.Invoke(jss, new object[] { inputContent });
filterContext.ActionParameters[Param] = result;
...

反射节省了一天。 感谢@Jason解释当type被指定为泛型方法(< Typename >)的一部分时,它会被编译成字节。 而作为属性,它可以是任何类型,只能在运行时确定。

UPDATE

对于此特定问题,以下代码更简洁。

var o = new DataContractJsonSerializer(JsonDataType).ReadObject(
    filterContext.HttpContext.Request.InputStream);
filterContext.ActionParameters[Param] = o;

错误

错误:' JsonFilter.JsonDataType '是'属性',但用作'类型'

告诉你确切的问题。

var result = jss.Deserialize<JsonDataType>(inputContent);

在这里,您尝试将JsonDataType作为类型参数传递给泛型方法JavaScriptSerializer.Deserialize<T>

但在这里

public Type JsonDataType { get; set; }

您将JsonDataType声明为Type的属性,但不是类型。 要使用泛型方法,您需要传递一个类型参数(或者,在某些情况下,让编译器推断一个)。 例如

var result = jss.Deserialize<string>(inputContent);

将是正确的用法,因为string是一种类型。

现在,如果您绝对想要使用由JsonDataType表示的类型,则可以使用反射。

MethodInfo generic = typeof(JavaScriptSerializer).GetMethod("Deserialize")
                                                 .GetGenericMethodDefinition();
MethodInfo closed = generic.MakeGenericMethod(new [] { JsonDataType });
closed.Invoke(jss, new object[] { inputContent });

由于您无法在类中添加泛型类型参数,因此您需要使用反射:

public class JsonFilter : ActionFilterAttribute
{
    public Type JsonDataType { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // ...
        JavaScriptSerializer jss = new JavaScriptSerializer();

        MethodInfo method = jss.GetType()
                               .GetMethod("Deserialize");
                               .MakeGenericMethod(new Type[] { JsonDataType });
        var result = method.Invoke(jss, new object[] { inputContent });
        //...
    }
}

原始的,错误的答案......

您可以使用泛型类型参数而不是 JsonDataType属性吗?

 
 
 
  
  public class JsonFilter<TJsonData> : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { // ... JavaScriptSerializer jss = new JavaScriptSerializer(); var result = jss.Deserialize<TJsonData>(inputContent); //... } }
 
  

沿着这些方向尝试这个。 我会在一秒钟内为您的代码更新它。

typeof(IDependencyResolver).GetMethod("Resolve", new Type[] { })
                .MakeGenericMethod(type)
                .Invoke(this, null);

这是给你的草稿。

typeof(JavaScriptSerializer).GetMethod("Deserialize", new Type[] {} /* param types */)
    .MakeGenericMethod(JsonDataType).Invoke(jss, /*params*/);

基本上它使用反射来调用泛型方法。

你不能以这种方式传递泛型类型的参数 - 尝试这样的事情:

public class JsonFilter<T> : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        JavaScriptSerializer jss = new JavaScriptSerializer();
        var result = jss.Deserialize<T>(inputContent);//Error here
    }
}

不要在属性中设置类型,而是使您的JsonFilter类通用,以便您可以将泛型类型参数传递给JavaScriptSerializer

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM