从 genericlist 获取索引项会引发错误

发布于 2024-09-30 06:10:22 字数 1845 浏览 5 评论 0原文

我试图从通用列表中按编号获取某个索引项,但得到: Unable tocast object of type 'System.Collections.Generic.List1[typename]' to type 'System.Collections .Generic.List1[System.Object]'。错误。

我想要实现的是基于继承的基类循环(向前或向后)到某个列表;像这样(或类似的东西):

public class Fruit
{
  public string Name {get;set;}
}
public class Apple : Fruit
{
  public bool IsSour {get;set;}
}
public class Orange : Fruit
{
  public bool Juicy {get;set;}
}
public List<Apple> Apples = new List<Apple>();
public List<Orange> Oranges = new List<Oranges>();

我想要的是这样的:

public string[] BuildList(object GenericListHere, bool Backwards)
{
  for(int i=GenericListHere.Length-1;i>=0;i--)
  {
    string MyName = GenericListHere[i].Name;

上面有点伪代码,但我想放入苹果或橙子列表以获得结果。 我事先不知道我要得到哪个对象,所以我得到像这样的计数/长度(不是伪编码),其中 TestObj 只是我得到的对象:

int iBound = -1;
try
{
    System.Reflection.PropertyInfo oInfo = TestObj.GetType().GetProperty("Count");
    iBound = (int)oInfo.GetValue(TestObj, null);
}
catch
{

如果 iBound >= 0 它是一个集合。下一部分..我有点迷失了...

 if (iBound != -1)
 {
      int iLoopStart = (backwardsLoop ? iBound - 1 : 0);
      int iLoopEnd = (backwardsLoop ? -1 : iBound);
      int iLoopDifference = (backwardsLoop ? -1 : +1);
      for (int iLoop = iLoopStart; iLoop != iLoopEnd; iLoop += iLoopDifference)
      {
           // THIS IS REALLY BAD CODED.. BUT I DONT GET IT
           object VarCollection = TestObj;
           object[] arInt = new object[1];
           arInt.SetValue(iLoop, 0);
           Type[] tArray = new Type[1];
           tArray.SetValue(typeof(int), 0);
           object oElem = ((System.Collections.Generic.List<object>)VarCollection)[iLoop];

我真正喜欢的是这样的东西:VarCollection[iLoop],但这似乎不起作用..

有人对此类列表有经验吗?蒂亚!

I'm trying to get a certain indexed item by number from a generic list and I'm getting: Unable to cast object of type 'System.Collections.Generic.List1[typename]' to type 'System.Collections.Generic.List1[System.Object]'. errors.

What I'm trying to achieve is to loop (forward or backwards) to a certain list based upon a inherited baseclass; like so (or something similar anyway):

public class Fruit
{
  public string Name {get;set;}
}
public class Apple : Fruit
{
  public bool IsSour {get;set;}
}
public class Orange : Fruit
{
  public bool Juicy {get;set;}
}
public List<Apple> Apples = new List<Apple>();
public List<Orange> Oranges = new List<Oranges>();

what I'd like to to is something like this:

public string[] BuildList(object GenericListHere, bool Backwards)
{
  for(int i=GenericListHere.Length-1;i>=0;i--)
  {
    string MyName = GenericListHere[i].Name;

The above is somewhat pseudocoded, but I'd like to throw in either the apples or oranges list to get result.
I don't know beforehand which object I'm getting, so I get the Count/Length like this (not psuedocoded) where TestObj is just the object I'm getting:

int iBound = -1;
try
{
    System.Reflection.PropertyInfo oInfo = TestObj.GetType().GetProperty("Count");
    iBound = (int)oInfo.GetValue(TestObj, null);
}
catch
{

And if the iBound >= 0 it's a collection. The next part.. I'm somewhat lost...

 if (iBound != -1)
 {
      int iLoopStart = (backwardsLoop ? iBound - 1 : 0);
      int iLoopEnd = (backwardsLoop ? -1 : iBound);
      int iLoopDifference = (backwardsLoop ? -1 : +1);
      for (int iLoop = iLoopStart; iLoop != iLoopEnd; iLoop += iLoopDifference)
      {
           // THIS IS REALLY BAD CODED.. BUT I DONT GET IT
           object VarCollection = TestObj;
           object[] arInt = new object[1];
           arInt.SetValue(iLoop, 0);
           Type[] tArray = new Type[1];
           tArray.SetValue(typeof(int), 0);
           object oElem = ((System.Collections.Generic.List<object>)VarCollection)[iLoop];

What I'd really like is something like : VarCollection[iLoop], but that doesn't seem to work..

Anyone experienced with these kind of lists? TIA!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

最偏执的依靠 2024-10-07 06:10:22

我真的认为反思并不是问题的答案;而是反思。泛型应该足以满足您的需求。看来您实际上并不需要通过索引访问列表中的元素,因为其目的似乎只是将一系列水果投影到一系列水果名称。但是,如果您确实需要通过索引访问元素(例如,如果您坚持使用for循环),那么如果您使用泛型,那么这应该不是问题; IList 上的索引器及其 Count 属性很容易在通用代码中发现。

以下使用通用约束的解决方案应该在 .NET 3.5 中正常工作:

public static string[] BuildList<T>(IList<T> list, bool backwards) 
    where T : Fruit
{
  var names = list.Select(fruit => fruit.Name);
  return (backwards ? names.Reverse() : names).ToArray();
}

在 .NET 4.0 中,List 被正确识别为IEnumerable。因此,以下签名也应该有效:

public static string[] BuildList(IEnumerable<Fruit> list, bool backwards) 

另一方面,您可能需要考虑返回 IEnumerable,并让调用者根据需要将结果推送到数组中。

I really think reflection isn't the answer here; generics should be more than enough for your needs. It also appears that you don't actually need to access elements from the list by index since the intention appears to simply be to project a sequence of fruits to a sequence of fruit-names. If you do need to access elements by index however (e.g. if you stick with your for loop), it shouldn't be an issue if you use generics; the indexer on IList<T> as well as its Countproperty is easily discoverable in generic code.

The following solution, which uses a generic constraint, should work fine in .NET 3.5:

public static string[] BuildList<T>(IList<T> list, bool backwards) 
    where T : Fruit
{
  var names = list.Select(fruit => fruit.Name);
  return (backwards ? names.Reverse() : names).ToArray();
}

In .NET 4.0, a List<Apple> is correctly recognized as anIEnumerable<Fruit>. Consequently, the following signature should work too:

public static string[] BuildList(IEnumerable<Fruit> list, bool backwards) 

On another note, you might want to consider returning an IEnumerable<string>instead, and let the caller push the results into an array if it so desires.

冰火雁神 2024-10-07 06:10:22

只需将其转换为 IList 并使用索引器即可。

Just cast it to IList and use the indexer.

如果您必须使用 object 和反射,您可能应该简单地使用非泛型 IList / ICollection 接口,而不是通用 IList / ICollection / List;你仍然会有索引器、迭代、添加等

In the case where you are having to work with object and reflection, you should probably simply use the non-generic IList / ICollection interfaces rather than the generic IList<T> / ICollection<T> / List<T>; you will still have indexer, iterate, add, etc

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文