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

问题描述 投票:38回答:8

有人可以帮我澄清一下吗。在我的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中指定的类型相同的类型,而我的代码可以是从BaseViewModel继承的任何类型的代码?可以以此方式推断我的模型/属性类型吗?

c# linq generics asp.net-mvc-2 expression
8个回答
15
投票

在您的示例中,编译器无法知道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" } };
    }
}

17
投票

我知道这个问题已经有了一个可以接受的答案,但是对我来说,.NET初学者来说,有一个简单的解决方案来解决我做错的事情,并认为我会分享。

我一直在这样做:

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

对我有用的东西正在变成这个:

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

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


14
投票

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

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


4
投票

此错误也与cache问题有关。

我遇到了同样的问题,仅通过清洁建筑解决了该问题。


3
投票

C#编译器只有lambda

arg => arg.MyProperty

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


0
投票

如果有帮助,在将null传递给通用TValue的参数时遇到了这个问题,要解决此问题,您必须强制转换为空值:

(string)null

(int)null


0
投票

我实际上是在寻找类似的错误,因此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。就这样。

所以请重新检查您的视图源代码...:-)


-3
投票

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

Model.GetHtmlAttributes

应该是

model.GetHtmlAttributes
© www.soinside.com 2019 - 2024. All rights reserved.