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

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

这个想法是每个 subview 模型都可以重写此方法,并基于某种逻辑提供一组合适的html属性,以在 View 中呈现:
<%: Html.TextBoxFor(model => model.MyProperty, Model.GetHtmlAttributes
                                                 (model => model.MyProperty)) %>

但是,当在上一行中使用时,点击 View 时会出现编译错误:



我必须执行以下操作:
<%: Html.TextBoxFor(model => model.MyProperty, Model.GetHtmlAttributes
                             <ChildModel, string>(model => model.MyProperty)) %>

我只是想了解它如何尝试推断类型,在HtmlHelper/TextBoxFor扩展方法中这样做没有问题吗?

是因为 View 中的HtmlHelper将自动具有与页面顶部ViewUserControl中指定的类型相同的类型,而我的代码却可以适用于从BaseViewModel继承的任何类型?可以以此方式推断我的模型/属性类型吗?

最佳答案

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

关于c# - 不能从用法中推断出类型实参。尝试显式指定类型参数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4969321/

10-13 07:44
查看更多