GetGenericArguments () [0] против GetGenericArguments () [1] в отношении анонимных типов в c # - PullRequest
0 голосов
/ 11 сентября 2018

Цель

Мне нужно представление списка, которое может отображать любой запрос, который я добавляю, без необходимости создания пользовательской модели представления или пользовательского представления.

Решение

Используя отражение, я могу передавать анонимные типы в пользовательские вспомогательные функции для создания всех заголовков и строк в таблице.

Проблема

Чтобы получить анонимный тип, мне нужно использовать метод GetGenericArguments() и оператор [], чтобы извлечь эту информацию. Однако когда я использую именованный Type (модель, которую я жестко запрограммировал), необходимый индекс для получения этого типа из строки IEnumerable<object> равен 0. Когда я использую анонимный тип, необходимый индекс равен 1. Почему это так, и есть ли лучший способ получить это Type?

Код

Контроллер:

(я могу передать любой из этих запросов модели в представление, и таблица отобразится соответственно)

public ActionResult Index()
{
    var models = taskService.ReadMany().Select(m => new
    {
        Name = m.Title,
        Summary = m.Details,
        Importance = m.Priority,
        DueDate = m.DateDue
    });
    var models = taskService.ReadMany();
    var models = taskService.ReadMany().GroupBy(m => new { m.DateDue }).Select(m => new { NumberOfProjects = m.Count(), DueOn = m.Key.DateDue });
    return View(models);
}

Вспомогательные расширения:

    public static MvcHtmlString BuildHeaders(this HtmlHelper html, Type type)
    {
        var tr = new TagBuilder("tr");
        var model = type;
        foreach (MemberInfo prop in model.GetProperties())
        {
            var th = new TagBuilder("th");
            var display = prop.GetCustomAttribute(typeof(DisplayAttribute)) as DisplayAttribute;
            if (display != null) th.InnerHtml = display.Name;
            else if (!prop.Name.Contains("Id")) th.InnerHtml = prop.Name;
            else continue;
            tr.InnerHtml += th.ToString();
        }
        return MvcHtmlString.Create(tr.ToString());
    }
    public static MvcHtmlString BuildRow(this HtmlHelper html, object model)
    {
        var tr = new TagBuilder("tr");
        var type = model.GetType();
        foreach (PropertyInfo prop in type.GetProperties())
        {
            var td = new TagBuilder("td");
            var val = prop.GetValue(model, null);
            string valString = "";
            if (val != null) valString = val.ToString();
            if (!prop.Name.Contains("Id")) td.InnerHtml = valString;
            else continue;
            tr.InnerHtml += td.ToString();
        }
        return MvcHtmlString.Create(tr.ToString());
    }

Список:

@model IEnumerable<object>
@{
    ViewBag.Title = "Index";
    Type type = Model.GetType().GetGenericArguments()[1]; //this line if I'm using an anonymous type
    Type type = Model.GetType().GetGenericArguments()[0]; //this line if I'm using a named type.  I need to make this line handle both situations without manual intervention

}
<h2>Index</h2>
<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    @Html.BuildHeaders(type)

@foreach (object item in Model) {
    @Html.BuildRow(item)
}
</table>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...