IEnumerable <t>?</t>的延迟迭代

时间:2014-02-15 07:51:42

标签: c# ienumerable generic-collections

尝试构建一个用于创建引导表的asp.net mvc html帮助器。我已经定义了我的流畅界面如下:

public interface IBootstrapObject: IHtmlString
{
    IBootstrapObject Name(string name);
    IBootstrapObject AddClass(params string[] classNames);
    //IBootstrapObject RemoveClass(params string[] classNames);
}

因此,实现类现在必须具有ToHtmlString()定义。此表助手将绑定的基础数据可能类似于List<Person>(假设Person它具有标准属性,如FirstNameLastName等。

因此说我已经定义了以下内容:

public class BootstrapTable : IBootstrapObject
{
    IEnumerable _dataSet;
    public IBootstrapObject DataSet<T>(IEnumerable<T> dataSet)
    {
        _modelType = typeof(T);
        _dataset = dataSet;
        return this;
    }

    public string ToHtmlString()
    {

    }

    //remaining code ...
}

如何访问IEnumerable<T>DataSet<T>()内传递的ToHtmlString()

从某种意义上说,我知道这涉及到将其缓存到某个地方,并在ToHtmlString()中重新访问它。这就是我使用_dataSet的原因。如何将IEnumerable转换为通用IEnumerable<T>

1 个答案:

答案 0 :(得分:2)

您无需以IEnumerable<T>的身份访问它。您可以使用非通用IEnumerable

var properties = _modelType.GetProperties(); // Or whatever... remove indexers etc
foreach (object item in _dataSet)
{
    foreach (var property in properties)
    {
        var value = property.GetValue(item, null);
        // Use the value somehow
    }
}

如果确实希望将其作为IEnumerable<T>,并且您不希望该类型本身是通用的,那么您将需要一个通用方法,您可以然后通过反射或使用动态类型来调用繁重的工作:

public string ToHtmlString()
{
    dynamic data = _dataSet;
    ToHtmlString(data);
}

private string ToHtmlString<T>(IEnumerable<T> data)
{
    ...
}

请注意,使用这样的动态类型,T可能与原始方法中的T不同。使用反射的另一种选择:

public string ToHtmlString()
{
    var method = typeof(BootstrapTable).GetMethod("ToHtmlStringImpl",
        BindingFlags.Instance | BindingFlags.NonPublic);
    var concreteMethod = method.MakeGenericMethod(_modelType);
    concreteMethod.Invoke(this, new object[] { _dataSet });
}

private string ToHtmlStringImpl<T>(IEnumerable<T> data)
{
    ...
}