在运行时C#反射中转换列表类型

时间:2016-10-31 17:31:36

标签: c# reflection casting

我一直在努力使用反射,但它对我来说仍然很新。所以下面的行可行。它返回DataBlockOne的列表

 var endResult =(List<DataBlockOne>)allData.GetType() 
.GetProperty("One")
.GetValue(allData);

但是直到运行时我才知道myType。所以我的想法是下面的代码,从返回的对象中获取类型,并将该类型转换为DataBlockOne列表。

List<DataBlockOne> one = new List<DataBlockOne>();
one.Add(new DataBlockOne { id = 1 });

List<DataBlockTwo> two = new List<DataBlockTwo>();
two.Add(new DataBlockTwo { id = 2 });

AllData allData = new AllData
{
    One = one,
    Two = two
};

var result = allData.GetType().GetProperty("One").GetValue(allData);

Type thisType = result.GetType().GetGenericArguments().Single();

注意我不知道下面的列表类型。我只是以DataBlockOne为例

 var endResult =(List<DataBlockOne>)allData.GetType() // this could be List<DataBlockTwo> as well as List<DataBlockOne>
.GetProperty("One")
.GetValue(allData);

我需要进行转换,以便稍后可以搜索列表(如果不转换返回的对象,则会出错)

if (endResult.Count > 0)
{
    var search = endResult.Where(whereExpression);
}

我混淆了类Type和列表中使用的类型。有人能指出我正确的方向在运行时获取类型并将其设置为列表的类型吗?

班级定义:

public class AllData
{
    public List<DataBlockOne> One { get; set; }
    public List<DataBlockTwo> Two { get; set; }
}

public class DataBlockOne
{
    public int id { get; set; }
}

public class DataBlockTwo
{
    public int id { get; set; }
}

2 个答案:

答案 0 :(得分:0)

你可能需要这样的东西:

var endResult = Convert.ChangeType(allData.GetType().GetProperty("One").GetValue(allData), allData.GetType());

猜测,自2013年以来没有在C#中工作,请不要拍摄:)

答案 1 :(得分:0)

你可能想要这样的东西:

static void Main(string[] args)
{
    var one = new List<DataBlockBase>();
    one.Add(new DataBlockOne { Id = 1, CustomPropertyDataBlockOne = 314 });

    var two = new List<DataBlockBase>();
    two.Add(new DataBlockTwo { Id = 2, CustomPropertyDatablockTwo = long.MaxValue });

    AllData allData = new AllData
    {
        One = one,
        Two = two
    };

    #region Access Base Class Properties
    var result = (DataBlockBase)allData.GetType().GetProperty("One").GetValue(allData);
    var oneId = result.Id;
    #endregion

    #region Switch Into Custom Class Properties
    if (result is DataBlockTwo)
    {
        var thisId = result.Id;
        var thisCustomPropertyTwo = ((DataBlockTwo)result).CustomPropertyDatablockTwo;
    }

    if (result is DataBlockOne)
    {
        var thisId = result.Id;
        var thisCustomPropertyOne = ((DataBlockOne)result).CustomPropertyDataBlockOne;
    }
    #endregion


    Console.Read();
}


public class AllData
{
    public List<DataBlockBase> One { get; set; }
    public List<DataBlockBase> Two { get; set; }
}

public class DataBlockOne : DataBlockBase
{
    public int CustomPropertyDataBlockOne { get; set; }
}

public class DataBlockTwo : DataBlockBase
{
    public long CustomPropertyDatablockTwo { get; set; }
}

public abstract class DataBlockBase
{
    public int Id { get; set; }
}