How to read an array of objects - c#

I have a C# list of objects and I'm trying to access its nested object. Here's the structure from Visual Studio's debugger (sorry I can't embed images since I'm a newbie to the site):
>product.Product {Product.AxdEntity_Product_EcoResProduct[1]}
>> - [0] {Product.EcoResProductMaster} // #1 - Please note curley braces
>>> - [Product.EcoResProductMaster] // #2 - Please note brackes
>>> + base {Product....
>>> + ModelingPolicy
>> + Identifier
To access the properties in #1, I would do the following:
var prod = product.Product[0];
Then I can access "Identifier" as such:
var identifier = prod.Identifier[0]...
To access the properties in #2 (such as ModelingPolicy), I'm not sure how to go about it:
var prod = product.Product[0][WhatShouldGoHere?].ModelingPolicy[0] ...?? I need help here
Eventually, I'd like to access the ModelingPolicy[0] like I did with prod.Identifier[0].
The Product class is being returned from a web service and I don't have access to its definition. At least I don't think I do.
Thank you for any guidance!

Looks to me like:
var ecoResProductMaster = product.Product[0].EcoResProductMaster; // Product type
var modelingPolicy = ecoResProductMaster.ModelingPolicy;
Have you tried this?

var productList = product.ToList()
foreach(var prod in productList)
{
var identifier = prod.identifier
foreach (var modelingPolicy in identifier.ModelingPolicy)
{
//do somthing with modeling policy
}
//do more stuff with product
}
As an aside please sort your naming conventions out. Having an array called product that contains a number of Product objects is just confusing

It's difficult to tell what you're going for here. Is this a List or array?
If it is a list then you can just foreach through the list to access each object.
Like if you have
List<SomeObject> someObjectList = new List<SomeObject>();
Then after you add a bunch of SomeObjects to the List you can just access the SomeObjects in a foreach loop.
foreach (SomeObject s in someObjectList)
{
// then to access nested objects
var n = s.SomeNestedObject;
// do something with n
}

Thanks all for your input. The answer from SmartDev helped me access the objects in the inner array. To do this, simply do the following:
var productMaster = (EcoResProductMaster)product.Product[0];
var modelingPolicy = productMaster.ModelingPolicy[0];
Of course, this is assuming that only one object is returned in the array, hence "[0]" but this should eventually go inside a foreach loop.
What I learned was if an object is returned without an index such as //#2 as noted above, a type cast should allow me to access it. However, if an index is returned such as //#1, then using [0] will allow me to access its properties.

Related

Why does this LINQ query new up only one instance of the internal List?

Upon request, I have simplified this question. When trying to take two generic List and blend them, I get unexpected results.
private List<ConditionGroup> GetConditionGroupParents()
{
return (from Conditions in dataContext.Conditions
orderby Conditions.Name
select new ConditionGroup
{
GroupID = Conditions.ID,
GroupName = Conditions.Name,
/* PROBLEM */ MemberConditions = new List<Condition>()
}).ToList();
}
private List<ConditionGroup> BuildConditionGroups()
{
var results = GetConditionGroupParents();
// contents of ConditionMaps is irrelevant to this matter
List<ConditionMap> ConditionMaps = GenerateGroupMappings();
// now pair entries from the map into their appropriate group,
// adding them to the proper List<MemberConditions> as appropriate
foreach (var map in ConditionMaps)
{
results.Find(groupId => groupId.GroupID == map.GroupID)
.MemberConditions.Add(new ConditionOrphan(map));
}
return results;
}
I would expect each map in ConditionMaps to be mapped to a single ConditionGroup's MemberConditions in the "results.Find...." statement.
Instead, each map is being added to the list of every group, and that happens simultaneously/concurrently.
[edit] I've since proven that there is only a single instance of
List<Memberconditions>, being referenced by each group.
I unrolled the creation of the groups like so:
.
.
.
/* PROBLEM */ MemberConditions = null }).ToList();
foreach (var result in results)
{
List<Condition> memberConditions = new List<Condition>();
results.MemberConditions = memberConditions;
}
return results;
In that case I was able to watch each instantiation stepping
through the loop, and then it worked as expected. My question
remains, though, why the original code only created a single
instance. Thanks!
.
Why doesn't the LINQ query in GetConditionGroupParents "new up" a unique MemberConditions list for each Group, as indicated in the /* PROBLEM */ comment above?
Any insight is appreciated. Thanks!
Jeff Woods of
Reading, PA
This is a bug. As a workaround you can create a factory function
static List<T> CreateList<T>(int dummy) { ... }
And pass it any dummy value depending on the current row such as Conditions.ID.
This trick works because L2S, unlike EF, is capable of calling non-translatable functions in the last Select of the query. You will not have fun migrating to EF since they have not implemented this (yet).

How to handle data from nested dictionary in C#

Im have setup a nested Dictionary as follows:
static Dictionary<string, Dictionary<UInt32, TClassType> > m_dictionary = new Dictionary<string, Dictionary<UInt32, TClassType>>();
The "TClassType" contains three attributes:
Title (string)
code (uint)
Address (string)
I add value to this nested structure as follows:
TClassType newEntry = new TClassType(s_title, ui_code, s_address)
if (! m_dictionary.ContainsKey(s_title))// check as the same s_title can occur multiple times but have different ui_code and s_address values
{
m_dictionary.Add(s_title, new Dictionary<uint, TClassType>());
}
m_dictionary[s_title].Add(ui_code, s_address);
Now my question is what is a good way to access all of the values for a specific key [s_title]?
the key [s_title] will contain many items within the nested Dictionary, and for a unique [s_title] entry I would like to obtain all of the relevant keys and values related to this outter key from within the nested Dictionary.
Sorry I hope that's not confusing, I find it as hard to ask as I do trying to implement.
Thank you all in advance
Try this:
if (m_dictionary.Contains(s_title))
foreach(TClassType entry in m_dictionary[s_title].Values)
// Do something with the entry.
Have you used linq before? This would be a prime usage for groupby. What you're doing adds a level of convolution.
With your current setup if you have a list of TClassType you would be able to use the linq where expression to grab only those with the title you are looking for and then the ui_code you need.
Edit for example (I was on mobile before which is hard to code on :))
IEnumerable<TClassType> entries = entriesList;//whatever you use to populate the entries
var titles = entries.Where(x=> x.s_title == "Title you're looking for").Distinct();

What is the correct way of ignoring arguments in LINQ?

I have the following code:
foreach (var b in userNames.Select(a => new User()))
{
...
}
This works quite well, since it gives me all "fresh" user objects, however Code Analysis complains that I shouldn't create unused locals, so my question is, is there a way of ignoring the arguments (similar to the "_" in Haskell).
PS: prehaps my example is not the best. I am sorry for this.
Thanks!
Update 1
I got the following code analysis error:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "a"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "b")]
_ is a perfectly valid variable name in C#. So writing
foreach(var b in userNames.Select(_ => new User()))
{
}
is perfectly valid code. It depends on your analysis rules whether it accepts such cases or not.
However, your code is indeed quite suspicious: you're mapping a collection of user names to a collection of users but you're not specifying a direct relation between the two: maybe you wanted to write something like this:
foreach(var b in userNames.Select(username => new User(username)))
To create a collection of objects of a given size, just use the length from the original collection.
var newColletion = Enumerable.Repeat(false, input.Length)
.Select(_ => new User());
but perhaps better would be your own helper method
static class MyEnumerable {
IEnumberable<T> Repeat<T>(Func<T> generator, int count) {
for (var i = 0; i < count; ++i) {
yield return generator();
}
}
}
and then use
var newCollection = MyEnumerable.Repeat(() => new User(), oldCollection.Length);
If quantity is your concern, and need linq, rewrite it as
foreach(var user in Enumerable.Repeat(()=>new User(),Usernames.Count).Select(x=>x()))
{
}
But, it may look ugly based on how you see it.
I'm sure there is a valid case where you would want to ignore arguments like this, but this doesn't seem like one of them. If you are creating N User objects for N userNames, surely you want to couple those together?
foreach (var b in userNames.Select(a => new { name = a, user = new User() }))
{
...
}
Then you won't have any unused arguments.
But the question remains why you aren't just doing this:
foreach (var name in userNames)
{
var user = new User();
// ...
}
As far as I can see, your use of .Select() makes no sense here.
Select performs a projection on the collection on which it is called, performing a specified operation on each element and returning the transformed results in another collection. If you do not need to perform any operation on the lambda element, you'd better simply create an array of User objects directly.
Answering your edit, as I said above, you can simply do this:
var NewColl = new User[userNames.Length];
As for initialization, you could have done this:
Enumerable.Repeat<User>(new User(), userNames.Length);

Accessing my objects array that has not been defined as an array

I wanted to use some amfphp functions in .NET and get access to some objects. After some searching I found a piece an opensource gateway that would do the trick.
How to use AMFPHP functions from .NET WPF application?
Ok here is were I am right now , and I could really use some help. After having made the connection and proper calls
public void Connect()
{
// Create NetConnection client
_netConnection = new NetConnection();
_netConnection.ObjectEncoding = ObjectEncoding.AMF0;
_netConnection.NetStatus += new NetStatusHandler(_netConnection_NetStatus);
_netConnection.Connect("http://www.mytestserver.nl/services/gateway");
System.Console.WriteLine("*** Flash RPC ***");
_netConnection.Call("amfphp.mytestserver.getObjects", new GetCustomersHandler(), new object[] { "415" });
System.Console.WriteLine("Press 'Enter' to exit");
}
And in my handler
public class GetCustomersHandler : IPendingServiceCallback
{
public void ResultReceived(IPendingServiceCall call)
{
object result = call.Result;
System.Console.WriteLine("Server response: " + result);
//DataAccess sample sends back an ArrayCollection (AMF3)
ArrayCollection items = result as ArrayCollection;
foreach (object item in items)
{
Flex.CustomerVO customer = item as Flex.CustomerVO;
System.Console.WriteLine(customer.firstname + " " + customer.lastname);
}
}
}
This is the way it is done in the project given in the samples folder.
I cannot iterate through the items , so I figured let me see how I can access my results object.
And here is were is it (at least for me) getting a bit tricky.
I can see the results as type object in my list , I can access the result array (?object) , but how do I iterate through my results objects in code since it is not an array. To clarify I added some screenshots.
http://imageshack.us/f/685/fluorine1.png/
as can be seen here results containing 46 items.
a little more clarification
http://imageshack.us/f/38/fluorine2.png/
(For instance I wish to access the Key, Value and such).
Does anyone have a solution or approach. It doesn't feel difficult(perhaps it is) but I seem to missing something.
Some help anyone?
It is indeed an array. It is an array of objects (object[]). You can access this like is shown in the example. The only problem is that you have to know what kind of object it is and cast it to that type.
Flex.CustomerVO customer = item as Flex.CustomerVO;
is where they cast the object.
If you want to iterate over the objects, you need to cast your result to an array of objects:
object[] objects = (objects)result;
Then you can access the individual items by casting again:
foreach (object obj in objects)
{
FluorineFx.ASObject asObject = (FluorineFx.ASObject)obj;
System.Console.WriteLine(asObject.Key);
}

Getting one list from another list using LINQ

I've seen the technique of taken a list of ObjectA and converting into a list of ObjectB where the two classes share some similar properties but is there an easier way to do that when you're just going from a list of ObjectA to another list of ObjectA?
Basically I want to do ...
var excv = from AuditedUser in data
where AuditedUser.IsMarkedForRemoval == false
select AuditedUser;
... but instead of a var I want the results to form a new List < AuditedUser > .
Is there something super easy I'm just missing?
var excv = (from AuditedUser in data
where AuditedUser.IsMarkedForRemoval == false
select AuditedUser).ToList();
I wrapped your LINQ statement with parens and added the ToList call at the end. Is this what you're looking for?
You could also do the following which is shorter to type and read I think:
List<AuditUser> excv = data.Where(a=>!a.IsMarkedForRemoval).ToList();

Categories

Resources