У меня есть приложение ASP.NET MVC, написанное на C #. В моем приложении есть очень специфический одноразовый метод расширения. В настоящее время мой метод расширения выглядит так

public static MvcHtmlString CreateControl<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, IEnumerable<SelectListItem> items, object htmlAttributes = null)
{
  var name = ExpressionHelper.GetExpressionText(expression);
  var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
  var model = htmlHelper.ViewData.Model;
  ...

  int i = 0;
  i = i + 1;
}

Я установил точку останова в строке с надписью int i = 0;. В окне "просмотра" в Visual Studio я могу увидеть список значений в model. model имеет свойство с именем "MyValue". Хотя я вижу это в окне «просмотра», я не могу понять, как получить значение «MyValue» из моего кода. model - это TModel. Кажется, я не могу преобразовать его тип. Вдобавок я не вижу вспомогательной функции или чего-то еще.

Как мне получить значение свойства из объекта TModel?

0
user70192 17 Фев 2015 в 17:45

2 ответа

Лучший ответ

модель TModel

TModel не является типом - это общий параметр . Ваш метод расширения является универсальным, то есть его можно запускать с любым типом модели. У компилятора нет возможности узнать во время компиляции, какие свойства имеет модель, поэтому нет возможности получить к ним доступ во время компиляции без отражения, приведения или динамического, все из которых небезопасны во время выполнения.

В моем приложении есть очень специфический метод одноразового расширения

Нет, это общий метод. Он может работать с любым типом модели. Если вы хотите, чтобы он относился к одному типу модели, не обобщайте тип модели:

                                                                  V----- specific type ----------------V
public static MvcHtmlString CreateControl<TValue>(this HtmlHelper<MyModel> htmlHelper, Expression<Func<MyModel, TValue>> expression, IEnumerable<SelectListItem> items, object htmlAttributes = null)
{
  var name = ExpressionHelper.GetExpressionText(expression);
  var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
  var model = htmlHelper.ViewData.Model;
  ...

  int i = 0;
  i = i + 1;
}
3
D Stanley 17 Фев 2015 в 14:55

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

public interface IMyModel
{
    MyValue { get; set; }
}

Теперь добавьте ограничение:

public static MvcHtmlString CreateControl<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, IEnumerable<SelectListItem> items, object htmlAttributes = null) 
    where TModel : IMyModel
{
    var myModel = (IMyModel)htmlHelper.ViewData.Model;
    //Now you can read the property:
    var value = myModel.MyValue;
}
2
DavidG 17 Фев 2015 в 14:52