Подтвердить что ты не робот

Аргументы типа не могут быть выведены из использования. Попробуйте явно указать аргументы типа

Может кто-то прояснит мне кое-что. В моем приложении 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? Можно ли написать это так, чтобы он мог выводить мои типы моделей/свойств?

4b9b3361

Ответ 1

В вашем примере компилятор не знает, какой тип должен 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, я думаю.

EDIT:

Собственно, вы можете сделать 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" } };
    }
}

Ответ 2

Я знаю, что этот вопрос уже имеет принятый ответ, но для меня, новичок .NET, было простое решение того, что я делал неправильно, и я думал, что поделюсь этим.

Я делал это:

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

Что сработало для меня, это изменилось:

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

(где "m" - произвольная строка для представления объекта модели)

Ответ 3

У меня была эта же проблема, мое решение:
В файле web.config:

<compilation debug="true>
пришлось изменить на
<compilation debug="true" targetFramework="4.0">

Ответ 4

Эта ошибка также связана с проблемой кеша.

У меня была та же проблема, и было решено только очистка и building.

Ответ 5

Компилятор С# имеет только lambda

arg => arg.MyProperty

для вывода типа arg (TModel) типа arg.MyProperty(TProperty). Это невозможно.

Ответ 6

В случае, если это помогает, я столкнулся с этой проблемой при передаче null в параметр для общего TValue, чтобы обойти это, вы должны указать свои нулевые значения:

(string)null

(int)null

и др.

Ответ 7

Вы имеете в виду тип, а не экземпляр. Сделайте "модель" в нижнем регистре в примере второго и четвертого образцов кода.

Model.GetHtmlAttributes

должен быть

Model.GetHtmlAttributes