简体   繁体   English

C#:如何访问ArrayList中的结构?

[英]C#: How to access structs in ArrayList?

It's probable the question of typization (in C++ with STL everything would be made through std::vector and no questions would appear). 可能是类型化问题(在带有STL的C ++中,所有内容都将通过std :: vector生成,并且不会出现任何问题)。

I have an ArrayList and I'd like to store some structs there. 我有一个ArrayList,我想在那里存储一些结构。 Like 喜欢

    struct txtRange
    {
        public String sText;
        public String sTag;
        public int iBeg;
        public int iEnd;
    };

    ArrayList Ranges = new ArrayList();   

    txtRange iRange;
    iRange.sText = entityText;
    iRange.sTag = "";
    iRange.iBeg = Ranges.Count > 0 ? Ranges[Ranges.Count - 1].iEnd + 1 : 0;
    iRange.iEnd = iRange.iBeg + tmpstr.Length;
    Ranges.Add(iRange);

Actually, I have troubles when accessing Ranges[Ranges.Count - 1].iEnd: 'object' does not contain a definition for 'iEnd'. 实际上,访问Ranges [Ranges.Count-1] .iEnd时遇到麻烦:“对象”不包含“ iEnd”的定义。 How should a ArrayList of the type specified be created? 如何创建指定类型的ArrayList?

The similar question ( How to cast object/structure into arraylist? ) made me laugh a bit... But still, there is an explanation how to add structures into ArrayList but not how to get the values from there. 类似的问题( 如何将对象/结构转换为arraylist? )让我有些笑...但是,仍然有一种解释,说明如何将结构添加到ArrayList中,但没有从那里获取值的方法。

You have three problems here: 您在这里遇到三个问题:

  1. You're using mutable structs. 您正在使用可变结构。 That's a bad idea to start with. 首先,这是一个坏主意。 Why isn't txtRange a class? 为什么txtRange不是类?

  2. You're using public fields - no encapsulation. 您正在使用公共字段-无封装。

  3. You're using the non-generic ArrayList type which means everything is getting boxed and you only have weak typing. 您使用的是非通用ArrayList类型,这意味着所有内容都将被装箱,并且您的输入类型很弱。

You can cast the result as you remove it, but then if you want to change the contents, you'll have to put it back again (because it's a struct, and is being copied each time). 您可以在删除结果时强制转换结果,但是如果要更改内容,则必须再次将其放回原处(因为它是一个结构,并且每次都会被复制)。 The snippet you've given doesn't actually need to change anything, but you're likely to run into it at some point. 您给出的代码片段实际上不需要进行任何更改,但是您可能会在某个时候碰到它。 Here's the snippet in working code: 这是工作代码中的代码段:

txtRange iRange;
iRange.sText = entityText;
iRange.sTag = "";
iRange.iBeg = Ranges.Count > 0 ? ((txtRange) Ranges[Ranges.Count - 1]).iEnd + 1 
                               : 0;
iRange.iEnd = iRange.iBeg + tmpstr.Length;
Ranges.Add(iRange);

However, I would suggest: 但是,我建议:

  • Rename txtRange to TextRange txtRange重命名为TextRange
  • Use a generic List<T> instead of ArrayList unless somehow you're working on a platform which doesn't support generics (the microframework or .NET 1.1) 除非使用某种不支持泛型的平台(微框架或.NET 1.1),否则请使用泛型List<T>而不是ArrayList
  • Either make TextRange immutable, or make it a class - or possibly both 无论是TextRange不变,或者使它成为一个类-或者可能两者都
  • Use properties instead of public fields (see here for more reasons) 使用属性代替公共字段(更多原因请参见此处
  • Avoid using abbreviations, and I would personally ditch the "i" prefix (I'd use Start, Tag, End, Text) 避免使用缩写,我个人会省略“ i”前缀(我会使用“开始”,“标记”,“结束”,“文本”)

As I see it, you just need to cast the output. 如我所见,您只需要转换输出即可。

((txtRange)Ranges[Ranges.Count-1]).iEnd 

Or use List<txtRange> instead for strongly typed loving. 或使用List<txtRange>代替强类型的爱。

You need to first cast it to a type of txtRange before you can access its propertys the way you specified. 您需要先将其转换为txtRange类型,然后才能以指定的方式访问其属性。

Or you can always go the List<T> where t is txtRange route as that will work without casting 或者,您也可以始终使用List<T> ,其中t是txtRange路由,因为它无需铸造就可以工作

iRange.iBeg = Ranges.Count > 0 ? ((txtRange)Ranges[Ranges.Count - 1]).iEnd + 1 : 0;

Thanks, the problem can both be solved by an explicit cast like 谢谢,问题都可以通过显式强制转换来解决

 iRange.iBeg = Ranges.Count > 0 ? ((txtRange)Ranges[Ranges.Count - 1]).iEnd + 1 : 0;

or by using generics. 或使用泛型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM