【问题标题】:Cast list item to generic type at runtime在运行时将列表项转换为泛型类型
【发布时间】:2015-02-08 17:08:40
【问题描述】:

我有如下界面:

interface IStorage
{ }

然后我有一个类派生自这个接口(它是通用的),例如,一个属性 Get

public class ManagingModel<T> : IStorage
{
    public Func<T> Get { get; set; }
}

要获得这些对象的列表,我使用List&lt;IStorage&gt;

问题是,如何将列表中的项目转换为ManagingModel&lt;&gt; 以访问此属性?

【问题讨论】:

  • 您应该提供房产名称
  • 你怎么知道你需要什么类型的? Func&lt;T&gt; 的调用代码是什么?
  • @Enigmativity,我的代码的用户将创建ManagingModel&lt;T&gt; 的实例,并使用Get 函数我会得到一些对象(没关系,用于什么目的)跨度>
  • @KonstantinVasilev - 这与从List&lt;IStorage&gt; 获取ManagingModel&lt;T&gt; 无关。调用代码需要对Func&lt;T&gt; 做什么?
  • @Enigmativity 我的代码只会检查它是否不为空,然后调用它并将结果传递给 View (asp.net mvc)。

标签: c# generics


【解决方案1】:

例如,您可以按索引访问列表元素。示例:

    var managingString = new ManagingModel<string>();
    var managingInt = new ManagingModel<int>();
    var managingDouble = new ManagingModel<double>();

    var list = new List<IStorage>();

    list.Add(managingString);
    list.Add(managingInt);
    list.Add(managingDouble);

尝试通过索引将“as”给定模型:

    var backToManagingModel = list[1] as ManagingModel<int>;

    if (backToManagingModel != null)
    {
        var get = backToManagingModel.Get;
    }

如果转换后 backToManagingModel 为空,那么它被转换为错误的类型,否则转换成功,你可以得到你的属性。

编辑:如果根本不使用泛型,而只是使用对象呢?

    public static string GetString()
    {
        return "xyz";
    }

    public interface IStorage
    {
        Func<object> Get { get; set; }
    }

    public class ManagingModel : IStorage
    {
        public Func<object> Get { get; set; }
    }

您不需要检查所有类型,只需致电list[index].Get

        var managingString = new ManagingModel
        {
            Get = new Func<string>(GetString)
        };

        var list = new List<IStorage>();

        list.Add(managingString);

        var get = list[1].Get;

【讨论】:

  • 感谢您的回答,但可能有很多类型(我无法控制它们会是哪一种)。所以我不能只检查所有可能的变体。
  • 更新后:是的,我考虑过这种方法,但我想在编译时使用泛型类型的灵活性。
【解决方案2】:

由于Func&lt;T&gt; 的值将用于视图,那么您可能可以将IStorage 扩展为Func&lt;object&gt;

试试这个:

interface IStorage
{
    Func<object> Get { get; }
}

public class ManagingModel<T> : IStorage
{
    public Func<T> Get { get; set; }

    Func<object> IStorage.Get
    {
        get
        {
            return () => this.Get();
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多