无法从用法推断出类型参数。尝试显式指定类型参数

时间:2011-02-11 13:05:30

标签: c# linq generics asp.net-mvc-2 expression

有人可以为我澄清一些事情。在我的ASP.NET MVC 2应用程序中,我有一个BaseViewModel类,其中包含以下方法:

public virtual IDictionary<string, object> GetHtmlAttributes<TModel, TProperty>
                        (Expression<Func<TModel, TProperty>> propertyExpression)
{
    return new Dictionary<string, object>();
}

这个想法是每个子视图模型都可以覆盖此方法,并根据某些逻辑提供一组合适的html属性,以便在视图中呈现:

<%: Html.TextBoxFor(model => model.MyProperty, Model.GetHtmlAttributes
                                                 (model => model.MyProperty)) %>

但是,当按照上面的行使用时,我在点击视图时出现编译错误:

  

无法从用法中推断出方法“...BaseViewModel.GetHtmlAttributes<TModel,TProperty> Expression<System.Func<TModel,TProperty>)”的类型参数。尝试明确指定类型参数。

我必须做以下事情:

<%: Html.TextBoxFor(model => model.MyProperty, Model.GetHtmlAttributes
                             <ChildModel, string>(model => model.MyProperty)) %>

我只想找到一些关于它如何推断类型的清晰度,在HtmlHelper/TextBoxFor扩展方法中这样做是没有问题的?

是否因为视图中的HtmlHelper将自动与页面顶部的ViewUserControl中指定的类型相同,而我的代码可以是继承自{{ 1}?有可能以这样的方式编写它,它可以推断我的模型/属性类型吗?

8 个答案:

答案 0 :(得分:17)

我知道这个问题已经有了一个公认的答案,但对于我来说,一个.NET初学者,有一个简单的解决方案,我做错了,我想我会分享。

我一直这样做:

@Html.HiddenFor(Model.Foo.Bar.ID)

对我有用的是改变这个:

@Html.HiddenFor(m => m.Foo.Bar.ID)

(其中“m”是表示模型对象的任意字符串)

答案 1 :(得分:14)

我有同样的问题,我的解决方案:
在web.config文件中:

<compilation debug="true>
必须改为
<compilation debug="true" targetFramework="4.0">

答案 2 :(得分:13)

在您的示例中,编译器无法知道TModel应该是什么类型。你可以做一些接近你可能尝试用扩展方法做的事情。

static class ModelExtensions
{
   public static IDictionary<string, object> GetHtmlAttributes<TModel, TProperty>
      (this TModel model, Expression<Func<TModel, TProperty>> propertyExpression)
   {
       return new Dictionary<string, object>();
   }
}

但我认为你无法与virtual类似。

修改

实际上,您可以使用自引用泛型来virtual

class ModelBase<TModel>
{
    public virtual IDictionary<string, object> GetHtmlAttributes<TProperty>
        (Expression<Func<TModel, TProperty>> propertyExpression)
    {
        return new Dictionary<string, object>();
    }
}

class FooModel : ModelBase<FooModel>
{
    public override IDictionary<string, object> GetHtmlAttributes<TProperty>
        (Expression<Func<FooModel, TProperty>> propertyExpression)
    {
        return new Dictionary<string, object> { { "foo", "bar" } };
    }
}

答案 3 :(得分:4)

此错误还与缓存问题有关。

我遇到了同样的问题,只是解决了清理构建解决方案。

答案 4 :(得分:3)

C#编译器只有lambda

arg => arg.MyProperty

用于推断类型的arg(TModel)是一种arg.MyProperty(TProperty)。这是不可能的。

答案 5 :(得分:1)

我实际上是在寻找类似的错误,因此Google向我发送了此问题。 错误是:

方法的类型参数 'IModelExpressionProvider.CreateModelExpression(ViewDataDictionary,Expression>)' 不能从用法中推断出

我花了大约15分钟试图弄清楚。这是在Razor .cshtml视图文件中发生的。 由于编译器的帮助不大,我不得不注释掉视图代码的某些部分,以防止遇到麻烦。

<div class="form-group col-2">
    <label asp-for="Organization.Zip"></label>
    <input asp-for="Organization.Zip" class="form-control">
    <span asp-validation-for="Zip" class="color-type-alert"></span>
</div>

你能发现吗?是的...我重新检查了两次,但一开始没有得到!

请注意,当ViewModel的属性应为Zip时,其属性仅为Organization.Zip。就是这样。

因此,请重新检查您的查看源代码...:-)

答案 6 :(得分:0)

如果它有帮助,我在将null传递给通用TValue的参数时遇到了这个问题,为了解决这个问题,你必须抛出空值:

(string)null

(int)null

答案 7 :(得分:-3)

您指的是类型而不是实例。在第二个和第四个代码示例中的示例中使'Model'小写。

Model.GetHtmlAttributes

应该是

model.GetHtmlAttributes