It's probable the question of typization (in C++ with STL everything would be made through std::vector and no questions would appear).
I have an ArrayList and I'd like to store some structs there. 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'. How should a ArrayList of the type specified be created?
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.
You have three problems here:
You're using mutable structs. That's a bad idea to start with. Why isn't txtRange
a class?
You're using public fields - no encapsulation.
You're using the non-generic ArrayList
type which means everything is getting boxed and you only have weak typing.
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:
txtRange
to TextRange
List<T>
instead of ArrayList
unless somehow you're working on a platform which doesn't support generics (the microframework or .NET 1.1) TextRange
immutable, or make it a class - or possibly both 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.
You need to first cast it to a type of txtRange before you can access its propertys the way you specified.
Or you can always go the List<T>
where t is txtRange route as that will work without casting
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.