Reputation: 1640
I am trying to use Linq to return a property of an object within an object. This is a simplified version of the program that demonstrates the behaviour.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp2
{
class Program
{
public class Associate
{
public string AssocType { get; set; }
public Contact contact { get; set; }
public Associate(string assocType)
{
AssocType = assocType;
//contact = new Contact("Contact 1", 1234);
//contact2 = new Contact("Contact 2", 23456);
}
}
public class Contact
{
string v1;
int v2;
public Contact(string v1, int v2) { this.v1 = v1; this.v2 = v2; }
public string Name { get; set; }
public int ID { get; set; }
}
static void Main(string[] args)
{
Associate assoc1 = new Associate("Type1");
assoc1.contact = new Contact("Contact 1", 9876);
Associate assoc2 = new Associate("Type2");
assoc2.contact = new Contact("Contact 2", 1234);
List<Associate> aList = new List<Associate>
{
assoc1,assoc2
};
var contactname = aList
.Where(s => s.AssocType == "Type1")
.Select(s => s.contact.Name)
.FirstOrDefault();
Console.Write(contactname);
Console.Read();
}
}
}
The contactname
variable is coming up as null but should return Contact 1
as a string. I have checked in the debugger and all the objects are set correctly and have the appropriate values. What am I doing wrong?
I also tried the below linq syntax (in place of the var contact name = aList...
part but I don't think it's correct as it won't compile due to Type inference failed
.
var name = from Associate in aList
from Contact in Associate
where Associate.AssocType == "Type1"
select Contact.Name;
Upvotes: 2
Views: 262
Reputation: 56453
In your Contact
class, you're never setting the Name
property so when you execute the below pipeline:
var contactname = aList.Where(s => s.AssocType == "Type1")
.Select(s => s.contact.Name)
.FirstOrDefault();
it's returning null
(not to be confused with the null
returned by FirstOrDefault
, this is the null
value of the Name
property as it's never been set ).
You can prove this with:
var count = aList.Count(s => s.AssocType == "Type1" && s.contact.Name == null);
Console.Write(count); // prints --> 1
So either, you meant:
var contactname = aList.Where(s => s.AssocType == "Type1")
.Select(s => s.contact.v1) // note the change
.FirstOrDefault();
assuming v1
is public.
or you'll explicitly need to populate the Name
property of the Contact
object sometime before the above pipeline.
Finally, for completeness if you want the query syntax then do:
var result = (from a in aList
where a.AssocType == "Type1"
select a.contact.Name)
.FirstOrDefault();
Upvotes: 3
Reputation: 5127
Contact name is null
because you have not initialised anywhere.
public Contact(string v1, int v2) { this.v1 = v1; this.v2 = v2; }
Either this should be
public Contact(string v1, int v2) { Name = v1; ID = v2; }
Or
public string Name { get; set; }
This should be (same for ID too)
public string Name { get { return v1; } }
Upvotes: 0