Instantiating nested classes shorthand - c#

I am trying to Fill a list of objects in this format so that it matches my JSON.NEt output for a needed API. But I am getting a NullReferenceException on the whole block starting with .Add()...Am I missing something?
foreach(var item in emailsToUpload.payload)
{
hubPayload.Add(new HubEmailItem()
{
email = item.Email, properties =
{ new HubEmailTuple() { property = "date", value = (DateTime.Now).ToString("d") },
new HubEmailTuple() { property = "other property", value = "other value" }
}
});
}
Update:
public class HubEmailItem
{
public String email { get; set; }
public List<HubEmailTuple> properties { get; set; }
}

You can't use this syntax with generic lists like this.
properties =
{ new HubEmailTuple() { property = "date", value = (DateTime.Now).ToString("d") },
new HubEmailTuple() { property = "other property", value = "other value" }
}
You should add a new List<HubSpotEmailTuple>
properties = new List<HubSpotEmailTuple>
{ new HubEmailTuple() { property = "date", value = (DateTime.Now).ToString("d") },
new HubEmailTuple() { property = "other property", value = "other value" }
}
Note: This is valid:
int[] a = {0, 2, 4, 6, 8};
But this is not:
// wrong
List<int> a = {0, 2, 4, 6, 8};
// correct
List<int> a = new List<int> {0, 2, 4, 6, 8};
Take a look at documentation: http://msdn.microsoft.com/en-us/library/aa664573(v=vs.71).aspx

The only thing that could throw this exception in case the List is initialized is one of the items you are iterating through. You are using the Email property and it seems that one of the items is null and is causing the exception.
email = item.Email //causes NullReferenceException when item is null
You can check if this is indeed true by setting a conditional breakpoint at the first curly brace of the foreach loop that will be triggered when item == null is true.

Related

Asserting a collection of objects is a part of another collection of objects of the same type

I'm trying to use .BeSubsetOf() from Fluent Assertions to ensure that one collection of objects is a subset of another, bigger collection of objects of the same type, but the assertion always fails.
Example code:
var expected = new[]
{
new Campus
{
Id = 1,
Name = "Campus 1"
},
new Campus
{
Id = 2,
Name = "Campus 2"
},
new Campus
{
Id = 3,
Name = "Campus 3"
}
};
var actual = new[]
{
new Campus
{
Id = 1,
Name = "Campus 1"
},
new Campus
{
Id = 2,
Name = "Campus 2"
}
};
actual.Should().BeSubsetOf(expected);
What's wrong here?
That is happening because BeSubsetOf use the object's
.Equals method for comparison.
One option is to override .Equals method of the type you are comparing.
Second alternative can be to verify one object at the time
foreach (var campus in actual)
{
expected.Should().ContainEquivalentOf(campus);
}

Binding multiple values to different variables in c# using for loop

How should i bind the values without using index no. as above, how can use forLoop here if possible. in query i gor 14 rows and 4 columns.
public class SLRInvestmentPrev
{
[DbCol("BOOK_VALUE")]
public double BOOK_VALUE { get; set; }
[DbCol("INSTRUMENT_ID")]
public int instrument_id { get; set; }
}
Public void Compute()
{
var slrinvestmentPrev = Database.BindList<SLRInvestmentPrev>(Transaction, #"Query here");
View["BOOK_VALUE_HTM0"] = slrinvestmentPrev[0].BOOK_VALUE;
View["BOOK_VALUE_HTM1"] = slrinvestmentPrev[1].BOOK_VALUE;
View["BOOK_VALUE_HTM2"] = slrinvestmentPrev[2].BOOK_VALUE;
View["BOOK_VALUE_HTM3"] = slrinvestmentPrev[3].BOOK_VALUE;
View["BOOK_VALUE_HFT1"] = slrinvestmentPrev[4].BOOK_VALUE;
View["BOOK_VALUE_HFT2"] = slrinvestmentPrev[5].BOOK_VALUE;
View["BOOK_VALUE_HFT3"] = slrinvestmentPrev[6].BOOK_VALUE;
View["BOOK_VALUE_HFT4"] = slrinvestmentPrev[7].BOOK_VALUE;
View["BOOK_VALUE_HFT5"] = slrinvestmentPrev[8].BOOK_VALUE;
View["BOOK_VALUE_AFS1"] = slrinvestmentPrev[9].BOOK_VALUE;
View["BOOK_VALUE_AFS2"] = slrinvestmentPrev[10].BOOK_VALUE;
View["BOOK_VALUE_AFS3"] = slrinvestmentPrev[11].BOOK_VALUE;
View["BOOK_VALUE_AFS4"] = slrinvestmentPrev[12].BOOK_VALUE;
View["BOOK_VALUE_AFS5"] = slrinvestmentPrev[13].BOOK_VALUE;
}
given your books are HTM0 to AFS5 you could do something like
List<String> booklist = new List<string>(new String[] { "BOOK_VALUE_HTM0", "BOOK_VALUE_HTM1", "BOOK_VALUE_HTM2",<.....> "BOOK_VALUE_AFS5" } ); // or populate from some other means
int index = 0;
foreach (String sbook in booklist)
{
View[sbook] = slrinvestmentPrev[index].BOOK_VALUE;
index++
}
how to bind that right side index values to different variables using
for loop or is there any way to make code short and being error free
if suppose to be rows no are less than hard coded index values?
So you need a way to bind your names to the indexes, one way it to use a Dictionary:
var nameIndexes = new Dictionary<int, string>()
{
{ 0, "BOOK_VALUE_HTM0" }, { 1, "BOOK_VALUE_HTM1" }, { 2, "BOOK_VALUE_HTM2" }, { 3, "BOOK_VALUE_HTM3" },
{ 4, "BOOK_VALUE_HFT1" }, { 5, "BOOK_VALUE_HFT2" }, { 6, "BOOK_VALUE_HFT3" }, { 7, "BOOK_VALUE_HFT4" }, { 8, "BOOK_VALUE_HFT5" },
{ 9, "BOOK_VALUE_AFS1" }, { 10, "BOOK_VALUE_AFS2" }, { 11, "BOOK_VALUE_AFS3" }, { 12, "BOOK_VALUE_AFS4" }, { 13, "BOOK_VALUE_AFS5" }
};
for(int i = 0; i < slrinvestmentPrev.Count; i++)
{
View[nameIndexes[i]] = slrinvestmentPrev[i].BOOK_VALUE;
}
If the index always starts with 0 and has no gaps you could also use a List<string> or string[].

How to filter List<object> using Linq/Lambda

Here is my scenario
List<object> obj = new List<object>();
obj.Add(new {id = 1, name = "Jakob"});
obj.Add(new {id = 2, name = "Sam"});
obj.Add(new {id = 3, name = "Albert"});
obj.Add(new {id = 1, name = "Jakob"});
How do you filter List<object> like these so it returns a List of users with name "Jakob"?
obj.Where(t => t.name == "Jakob") doesn't work
The best option you have is to declare a class that represents a user.
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
Then create a list of User objects and query this list.
var users = new List<User>
{
new User { Id = 1, Name = "Jakob" },
new User { Id = 2, Name = "Sam" },
new User { Id = 3, Name = "Albert" }
}
var filteredUsers = users.Where(user => user.Name == "Jakob");
Otherwise, you have to rely on the solution that Tengiz suggested.
If you convert your object to dynamic, it should work:
obj.Where(t => ((dynamic)t).name == "Jakob")
EDIT:
For completeness, I should mention couple of things:
Usage of dynamic type comes down to usage of object with reflection on top of it, so eventually you don't get something better than reflection if you use this approach.
Usage of dynamic at all involves loading necessary assemblies (a.k.a. DLR) into CLR, which would not load if you don't use dynamic at all. In other words, it's an overhead.
So, use with your own discretion.
Yet another alternative is create array of anonymous types and then convert it to list via ToList IEnumerable extension method:
var obj = (new[] {
new { id = 1, name = "Jakob" },
new { id = 2, name = "Sam" },
new { id = 3, name = "Albert" },
new { id = 1, name = "Jakob" }}).ToList();
obj.Where(c => c.name == "Jakob");
If you don't really need a list and array is fine too - just don't convert to list. Benefit is you got strongly typed list and not list of arbitrary objects.
You could use reflection
var l = new List<object>();
l.Add(new {key = "key1", v = "value1"});
l.Add(new {key = "key2", v = "value2", v2="another value"});
l.Add(new {key = "key3", v = "value3", v3= 4});
l.Add(new {key = "key4", v = "value4", v4 = 5.3});
var r = l.Where(x=> (string)x.GetType().GetProperty("key")?.GetValue(x) == "key1");
Get the type of your elements and find the property you are looking for. Then get the value for the current instance and compare it to the value you want to filter for.
But on the other hand, this approach has the advantage of working even if the List contains items of several different anonymous types (if they have different properties), as long as they all have the property you are filtering for.
EDIT
With c# 6 you can use the ? operator, which is sort of an inline check for null. Ie, if GetProperty() returns null because the property is not found, the expression returns null without executing GetValue() (which would otherwise throw a NullReferenceException)

Why does using IEnumerable<T> inside a recursive method make it much slower than using a List<T>?

I am using a recursive method to go through a tree of items and add its children to a flat collection:
public class Thing
{
public int Id { get; set; }
public string Name { get; set; }
public int? ParentId { get; set; }
}
void Main()
{
var sampleData = new List<Thing>
{
new Thing { Id = 1, Name = "root1", ParentId = null },
new Thing { Id = 2, Name = "2", ParentId = 1 },
new Thing { Id = 3, Name = "3", ParentId = 1 },
new Thing { Id = 4, Name = "4", ParentId = 2 },
new Thing { Id = 5, Name = "5", ParentId = 2 },
new Thing { Id = 6, Name = "6", ParentId = 2 },
new Thing { Id = 7, Name = "7", ParentId = 6 },
new Thing { Id = 8, Name = "8", ParentId = 7 },
new Thing { Id = 9, Name = "9", ParentId = 8 },
new Thing { Id = 10, Name = "10", ParentId = 9 },
new Thing { Id = 11, Name = "11", ParentId = 10 },
new Thing { Id = 12, Name = "12", ParentId = 11 },
new Thing { Id = 13, Name = "13", ParentId = 12 },
new Thing { Id = 14, Name = "14", ParentId = 13 },
new Thing { Id = 15, Name = "root15", ParentId = null }
};
var subThings = new HashSet<Thing>();
var stopWatch = new Stopwatch();
stopWatch.Start();
//AddSubThings(subThings, sampleData, new List<int> { 1 });
AddSubThingsUsingList(subThings, sampleData, new List<int> { 1 });
stopWatch.Elapsed.Dump();
subThings.Dump();
}
private void AddSubThings(HashSet<Thing> resultThings, IEnumerable<Thing> sourceThings, IEnumerable<int> parentIds)
{
if (!sourceThings.Any() || !parentIds.Any())
{
return;
}
var subThings = sourceThings.Where(st => st.ParentId.HasValue && parentIds.Contains(st.ParentId.Value));
resultThings.UnionWith(subThings);
AddSubThings(resultThings, sourceThings.Except(subThings), subThings.Select(st => st.Id));
}
private void AddSubThingsUsingList(HashSet<Thing> resultThings, List<Thing> sourceThings, List<int> parentIds)
{
if (!sourceThings.Any() || !parentIds.Any())
{
return;
}
var subThings = sourceThings.Where(st => st.ParentId.HasValue && parentIds.Contains(st.ParentId.Value));
resultThings.UnionWith(subThings);
AddSubThingsUsingList(resultThings, sourceThings.Except(subThings).ToList(), subThings.Select(st => st.Id).ToList());
}
When I use the AddSubThings method it takes around 90 seconds to process. However if I use the AddSubThingsUsingList method it does not even take a second. Why is this?
The problem is because your create subThings from sourceThings like this
var subThings = sourceThings.Where(
st => st.ParentId.HasValue && parentIds.Contains(st.ParentId.Value));
Then you pass the following as sourceThings to the recursive call.
sourceThings.Except(subThings)
Which is equivalent to
sourceThings.Except(
sourceThings.Where(
st => st.ParentId.HasValue && parentIds.Contains(st.ParentId.Value)))
That query when iterated with have to iterate over the original list twice. With each recursive call the query will build up and need to iterate the original list 2^n times where n is the recursion level. And your query is being iterated by the Any and the HashSet.UnionWith calls meaning it's more like 2^(n+1).
The other one immediately iterates the query before passing them and thus avoids this doubling problem.
You could pass the following to your recursive call for sourceThings instead to make it faster as it doesn't double up the required iterating of the original list on each recursive call.
sourceThings.Where(st => !st.ParentId.HasValue || !parentIds.Contains(st.ParentId.Value))
Ok. This is a bit complex.
Operations on IEnumerable are lazy, i.e. they are not executed until you need the result. Now when you pass sourceThins and subThings to AddSubThings, you've not sent a materialized collection of things, all you've done is you've defined how these collections are calculated from the original Lists.
Now when the method calls itself recursively, it adds more filtering and selection to the data it has received.
All these layers of selection and filtering will be called when you call Any().
On the other hand, in the case of Lists, things are materialized after calls to Where, Except and Select, because you call ToList.

C# and arrays of anonymous objects

What does such an expression mean?
obj.DataSource = new[]
{
new {Text = "Silverlight", Count = 10, Link="/Tags/Silverlight" },
new {Text = "IIS 7", Count = 11, Link="http://iis.net" },
new {Text = "IE 8", Count = 12, Link="/Tags/IE8" },
new {Text = "C#", Count = 13, Link="/Tags/C#" },
new {Text = "Azure", Count = 13, Link="?Tag=Azure" }
};
Especially these lines: new {Text = "IIS 7"... }
How can I create an array like this manually to suit this DataSource.
First, let's reformat that code a little:
obj.DataSource = new[]
{
new { Text = "Silverlight", Count = 10, Link = "/Tags/Silverlight" },
new { Text = "IIS 7", Count = 11, Link = "http://iis.net" },
new { Text = "IE 8", Count = 12, Link = "/Tags/IE8" },
new { Text = "C#", Count = 13, Link = "/Tags/C#" },
new { Text = "Azure", Count = 13, Link = "?Tag=Azure" }
};
This does not look like a multi-dimensional array, but rather like an array of 5 objects. These objects inside the array are of an anonymous type, created and initialized using new { ... }.
Concerning your question how you can manually create such an array to suit the data source: you seem to be doing exactly that with the above code.
That's not a multidimensional array. That's an array of objects which have been created using object initializers with anonymous types.
Looks like an array of anonymous types.
http://msdn.microsoft.com/en-us/library/bb397696.aspx
Just to add: Anonymous types are converted by the compiler to a real object. So the code will be changed to something equivalent of this (MUCH simplified, only to show that the compiler will create an actual class):
internal sealed class AnonymousClass1
{
internal string Text { get; set; }
internal int Count { get; set; }
internal string Link { get; set; }
}
And your code will then be changed to:
obj.DataSource = new AnonymousClass1[]
{
new AnonymousClass1 {Text = "Silverlight", Count = 10, Link="/Tags/Silverlight" },
new AnonymousClass1 {Text = "IIS 7", Count = 11, Link="http://iis.net" },
new AnonymousClass1 {Text = "IE 8", Count = 12, Link="/Tags/IE8" },
new AnonymousClass1 {Text = "C#", Count = 13, Link="/Tags/C#" },
new AnonymousClass1 {Text = "Azure", Count = 13, Link="?Tag=Azure" }
};
In one of my programs, I have code like this (simplified!):
var myObjects = new []{
new { Id = Guid.NewGuid(), Title = "Some Title", Description = string.Empty },
new { Id = Guid.NewGuid(), Title = "Another Title", Description = string.Empty },
new { Id = Guid.NewGuid(), Title = "Number 3", Description = "Better than No2, but not much" }
}
foreach(var myObject in myObjects) {
DoSomeThingWith(myObject.Title);
}
This works because it is just another class (I even get IntelliSense) behind the scenes. The benefit is obviously that I just saved myself from creating a class for this object. In my example, all objects need to look the same as well. (Obviously, doing this for any public members would be a bad idea as the compiler might change the name of the anonymous class if you add/remove some)
It's making a new object array, containing a group of anonymous objects.
new {Text = "Azure", Count = 13, Link="?Tag=Azure" }
is not creating a hash like similar syntax in say php would, but rather real a real object with the properties Test, Count, and Link set.
A good primer for anonymous objects can be found here
You should be able to use the same syntax to create new structures like this, the property values do not have to be constants:
string text = "Azure";
int count = 13;
string link = "?Tag=Azure";
new {Text = text, Count = count, Link=link }
To return such an array from a function I used:
public object GetAnonymousArray()
{
var tbl = new List<object>();
while (___)
{
//fill array in cycle
tbl.Add(new {Text = someString, Count = someInt, Link = link});
}
return tbl;
}

Categories