I have a GroupSummary class that has some properties like this in it:
public class GroupsSummary
{
public bool FooMethod()
{
////
}
public bool UsedRow { get; set; }
public string GroupTin { get; set; }
public string PayToZip_4 { get; set; }
public string PayToName { get; set; }
public string PayToStr1 { get; set; }
public string PayToStr2 { get; set; }
public string PayToCity { get; set; }
public string PayToState { get; set; }
public bool UrgentCare_YN { get; set; }
}
Then I have a Dictionary like <string, List<GroupsSummary>
For each of these dictionary items I want to find all the distinct addresses but the properties of this class that define a distinct address for me are
PayToStr1,PayToStr2,PayToCity,PayToState
I know as far as I can say something like mydictionartItem.select(t => t).Distinct().ToList() but I think that will compare all the properties of this class which is wrong. So how should I solve this?
var newDict = dict.ToDictionary(
x=>x.Key,
v=>v.Value.GroupBy(x=>new{x.PayToStr1, x.PayToStr2, x.PayToCity, x.PayToState})
.Select(x=>x.First())
.ToList());
implement IEquatable<T> interface on the GroupsSummary Class. More information can be found here
IEquatable
defines a method Equals. Remember to overload the GetHashCode method as well
Write your own IEqualityComparer, like so:
public class GroupsSummaryComparer : IEqualityComparer<GroupsSummary>
{
public bool Equals(GroupsSummary x, GroupsSummary y)
{
if (object.ReferenceEquals(x, y))
return true;
else if (object.ReferenceEquals(x, null) || object.ReferenceEquals(y, null))
return false;
return x.PayToStr1 == y.PayToStr1 && x.PayToStr2 == y.PayToStr2 && x.PayToCity == y.PayToCity && x.PayToState == y.PayToState;
}
public int GetHashCode(GroupsSummary obj)
{
if (obj == null)
return 0;
int code;
if (obj.PayToStr1 != null)
code ^= obj.PayToStr1.GetHashCode();
if (obj.PayToStr2 != null)
code ^= obj.PayToStr2.GetHashCode();
if (obj.PayToCity != null)
code ^= obj.PayToCity.GetHashCode();
if (obj.PayToState != null)
code ^= obj.PayToState.GetHashCode();
return code;
}
}
Then you can pass it to Distinct
This may be safer than implementing IEquatable<GroupsSummary> directly on the class, since, in other situations, you may want to test them for full equality.
The easiest way would be to implement an IEqualityComparer<GroupsSummary>
Then you can say something like
HashSet<GroupSummary> unique = new HashSet<GroupsSummary>(
myDict.Values ,
new MyGroupsSummaryEqualityComparer()
) ;
Related
I have these classes:
public class AlertEvaluation
{
public string AlertId { get; set; }
public ICollection<EvaluatedTag> EvaluatedTags { get; set; }
public string TransactionId { get; set; }
public EvaluationStatus EvaluationStatus { get; set; }
public DateTime EvaluationDate { get; set; }
}
public class EvaluatedTag
{
public string Id { get; set; }
public string Name { get; set; }
}
And I would like to get a list of alert evaluations grouped by AlertId, and by EvaluatedTags, meaning that I would like to compare and group evaluations that not only have the same AlertId, but to also have the same list of EvaluatedTags. (And also get the last evaluation in time)
I tried this:
var evaluationsGroupedAndOrdered = evaluations.GroupBy(x => new { x.AlertSettingId, x.EvaluatedLabels })
.Select(x => x.OrderByDescending(z => z.EvaluationDate ).FirstOrDefault()).ToList();
But of course, the comparing of list properties like that did not work.
I read something about adding an equality comparer in GroupBy, which would mean comparing the lists inside the objects right? But I'm not sure of how to implement it in the right way.
I tried (based on GroupBy on complex object (e.g. List<T>)) :
public class AlertEvaluationComparer : IEqualityComparer<AlertEvaluation>
{
public bool Equals(AlertEvaluation x, AlertEvaluation y)
{
return x.AlertId == y.AlertId && x.EvaluatedTags.OrderBy(val => val.Name).SequenceEqual(y.EvaluatedTags.OrderBy(val => val.Name));
}
public int GetHashCode(AlertSettingEvaluation x)
{
return x.AlertId.GetHashCode() ^ x.EvaluatedTags.Aggregate(0, (a, y) => a ^ y.GetHashCode());
}
}
But did not work either.. Maybe because my list EvaluatedTags is not a list of strings but of individual objects.
Does anybody have a nice solution for this?
A typical way to compare two lists is to use the System.Linq exension method, SequenceEquals. This method returns true if both lists contain the same items, in the same order.
In order to make this work with an IEnumerable<EvaluatedTag>, we need to have a way to compare instances of the EvaluatedTag class for equality (determining if two items are the same) and for sorting (since the lists need to have their items in the same order).
To do this, we can override Equals and GetHashCode and implement IComparable<EvaluatedTag> (and might as well do IEquatable<EvaluatedTag> for completeness):
public class EvaluatedTag : IEquatable<EvaluatedTag>, IComparable<EvaluatedTag>
{
public string Id { get; set; }
public string Name { get; set; }
public int CompareTo(EvaluatedTag other)
{
if (other == null) return -1;
var result = string.CompareOrdinal(Id, other.Id);
return result == 0 ? string.CompareOrdinal(Name, other.Name) : result;
}
public bool Equals(EvaluatedTag other)
{
return other != null &&
string.Equals(other.Id, Id) &&
string.Equals(other.Name, Name);
}
public override bool Equals(object obj)
{
return Equals(obj as EvaluatedTag);
}
public override int GetHashCode()
{
return Id.GetHashCode() * 17 +
Name.GetHashCode() * 17;
}
}
Now we can use this in the custom comparer you have in your question, for sorting and comparing the EvaluatedTags:
public class AlertEvaluationComparer : IEqualityComparer<AlertEvaluation>
{
// Return true if the AlertIds are equal, and the EvaluatedTags
// contain the same items (call OrderBy to ensure they're in
// the same order before calling SequenceEqual).
public bool Equals(AlertEvaluation x, AlertEvaluation y)
{
if (x == null) return y == null;
if (y == null) return false;
if (!string.Equals(x.AlertId, y.AlertId)) return false;
if (x.EvaluatedTags == null) return y.EvaluatedTags == null;
if (y.EvaluatedTags == null) return false;
return x.EvaluatedTags.OrderBy(et => et)
.SequenceEqual(y.EvaluatedTags.OrderBy(et => et));
}
// Use the same properties in GetHashCode that were used in Equals
public int GetHashCode(AlertEvaluation obj)
{
return obj.AlertId?.GetHashCode() ?? 0 * 17 +
obj.EvaluatedTags?.Sum(et => et.GetHashCode() * 17) ?? 0;
}
}
And finally we can pass your AlertEvaluationComparer to the GroupBy method to group our items:
var evaluationsGroupedAndOrdered = evaluations
.GroupBy(ae => ae, new AlertEvaluationComparer())
.OrderBy(group => group.Key.EvaluationDate)
.ToList();
Here's a go at it, getting away from Linq a bit to make it easier to build the groups one at a time while leveraging sorting:
// Build groups by using a combination of AlertId and EvaluatedTags hashcode as group key
var groupMap = new Dictionary<string, SortedSet<AlertEvaluation>>();
foreach (var item in evals)
{
var combinedKey = item.AlertId + EvaluatedTag.GetCollectionHashCode(item.EvaluatedTags);
if (groupMap.TryGetValue(combinedKey, out SortedSet<AlertEvaluation>? groupItems))
{
// Add to existing group
groupItems.Add(item);
}
else
{
// Create new group
groupMap.Add(combinedKey, new SortedSet<AlertEvaluation> { item });
}
}
// Get a list of groupings already sorted ascending by EvaluationDate
List<SortedSet<AlertEvaluation>>? groups = groupMap.Values.ToList();
This assumes that the classes implement IComparable and Equals/GetHashCode to facilitate sorting:
public class AlertEvaluation : IComparable<AlertEvaluation>
{
public string AlertId { get; set; }
public ICollection<EvaluatedTag> EvaluatedTags { get; set; }
public string TransactionId { get; set; }
public EvaluationStatus EvaluationStatus { get; set; }
public DateTime EvaluationDate { get; set; }
// Used by SortedSet
public int CompareTo(AlertEvaluation? other)
{
if (other is null)
{
return 1;
}
return EvaluationDate.CompareTo(other.EvaluationDate);
}
}
public class EvaluatedTag : IEquatable<EvaluatedTag?>
{
public string Id { get; set; }
public string Name { get; set; }
public bool Equals(EvaluatedTag? other) => other != null && Id == other.Id && Name == other.Name;
public override int GetHashCode() => HashCode.Combine(Id, Name);
// Helper to get a hash of item collection
public static int GetCollectionHashCode(ICollection<EvaluatedTag> items)
{
var code = new HashCode();
foreach (var item in items.OrderBy(i => i.Id))
{
code.Add(item);
}
return code.ToHashCode();
}
}
By the way, I'm using the fancy new HashCode class in .NET Core to override hash codes.
Edit:
_existingRatings and _targetRatings are both collections from a database, where Rating and RatingType are both key/values.
I've got two RatingDto collections that I need to compare each other against: _existingRates and _targetRates. I'll be simply doing a comparison on the RatingTypeId, then need to check if the same one in the _targetRates has an empty Rating string.
As it's Monday morning, my brain is still asleep and I'm sure there's a better and simpler way to do this with LINQ. This is what I'm currently doing:
class RatingDto
{
public int RatingTypeId { get; set; }
public string RatingType { get; set; }
public string Rating { get; set; }
}
foreach (var existing in _existingRatings)
{
foreach(var target in _targetRatings)
{
if(existing.RatingTypeId == target.RatingTypeId)
{
if(target.Rating == string.Empty)
{
_targetHasMissingRatings = true;
}
}
}
}
This should be okay as the maximum amount is around 7 in each collection, but I'm sure there's a better and cleaner way with LINQ.
That's should what you are looking for :
(i love to use string.IsNullOrEmpty rather than cmp string.Empty)
_targetHasMissingRatings = _existingRatings.Any(er => string.IsNullOrEmpty(_targetRatings.FirstOrDefault(tr => er.RatingTypeId == tr.RatingTypeId)?.Rating));
Use IComparable so you can use OrderBy on the entire class or simply compare two instances of the class.
List<RatingDto> ordered = _existingRatings.OrderBy(x => x).ToList();
See code below :
class RatingDto : IComparable<RatingDto>
{
public int RatingTypeId { get; set; }
public string RatingType { get; set; }
public string Rating { get; set; }
public int CompareTo(RatingDto other)
{
if (this.RatingTypeId != other.RatingTypeId)
{
return this.RatingTypeId.CompareTo(other.RatingTypeId);
}
else
{
return this.RatingType.CompareTo(other.RatingType);
}
}
}
Code would look like this :
List<RatingDto> _existingRatings = new List<RatingDto>();
List<RatingDto> _targetRatings = new List<RatingDto>();
Boolean _targetHasMissingRatings = false;
foreach (var existing in _existingRatings)
{
foreach (var target in _targetRatings)
{
if (existing == target)
{
_targetHasMissingRatings = true;
break;
}
}
if (_targetHasMissingRatings == true) break;
}
This question already has answers here:
What's the best strategy for Equals and GetHashCode?
(7 answers)
Closed 9 years ago.
I have never really done this before so i was hoping that someone could show me the correct what of implementing a override of Except() and GetHashCode() for my class.
I'm trying to modify the class so that i can use the LINQ Except() method.
public class RecommendationDTO{public Guid RecommendationId { get; set; }
public Guid ProfileId { get; set; }
public Guid ReferenceId { get; set; }
public int TypeId { get; set; }
public IList<TagDTO> Tags { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime? ModifiedOn { get; set; }
public bool IsActive { get; set; }
public object ReferencedObject { get; set; }
public bool IsSystemRecommendation { get; set; }
public int VisibilityScore { get; set; }
public RecommendationDTO()
{
}
public RecommendationDTO(Guid recommendationid,
Guid profileid,
Guid referenceid,
int typeid,
IList<TagDTO> tags,
DateTime createdon,
DateTime modifiedon,
bool isactive,
object referencedobject)
{
RecommendationId = recommendationid;
ProfileId = profileid;
ReferenceId = referenceid;
TypeId = typeid;
Tags = tags;
CreatedOn = createdon;
ModifiedOn = modifiedon;
ReferencedObject = referencedobject;
IsActive = isactive;
}
public override bool Equals(System.Object obj)
{
// If parameter is null return false.
if (obj == null)
{
return false;
}
// If parameter cannot be cast to Point return false.
RecommendationDTO p = obj as RecommendationDTO;
if ((System.Object)p == null)
{
return false;
}
// Return true if the fields match:
return (ReferenceId == p.ReferenceId);// && (y == p.y);
}
public bool Equals(RecommendationDTO p)
{
// If parameter is null return false:
if ((object)p == null)
{
return false;
}
// Return true if the fields match:
return (ReferenceId == p.ReferenceId);// && (y == p.y);
}
//public override int GetHashCode()
//{
// return ReferenceId;// ^ y;
//}}
I have taken a look at http://msdn.microsoft.com/en-us/library/ms173147.aspx but i was hoping someone could show me within my own example.
Any help would be appreciated.
Thank you
You can override Equals() and GetHashCode() on your class like this:
public override bool Equals(object obj)
{
var item = obj as RecommendationDTO;
if (item == null)
{
return false;
}
return this.RecommendationId.Equals(item.RecommendationId);
}
public override int GetHashCode()
{
return this.RecommendationId.GetHashCode();
}
public override bool Equals(System.Object obj)
{
// Check if the object is a RecommendationDTO.
// The initial null check is unnecessary as the cast will result in null
// if obj is null to start with.
var recommendationDTO = obj as RecommendationDTO;
if (recommendationDTO == null)
{
// If it is null then it is not equal to this instance.
return false;
}
// Instances are considered equal if the ReferenceId matches.
return this.ReferenceId == recommendationDTO.ReferenceId;
}
public override int GetHashCode()
{
// Returning the hashcode of the Guid used for the reference id will be
// sufficient and would only cause a problem if RecommendationDTO objects
// were stored in a non-generic hash set along side other guid instances
// which is very unlikely!
return this.ReferenceId.GetHashCode();
}
Be careful when using a primary key as your test for equality in overriding Equals() because it only works AFTER the object has been persisted. Prior to that your objects don't have primary keys yet and the IDs of the ones in memory are all zero.
I use base.Equals() if either of the object IDs is zero but there probably is a more robust way.
I have a bussiness object like this:
[PetaPoco.TableName("cars")]
[PetaPoco.PrimaryKey("id")]
public class Cars : CarObject
{
[DefaultValue(null)]
[DisplayName("Column Name")]
public string Color { get; set; }
[DefaultValue(null)]
public string Engine { get; set; }
[DefaultValue(null)]
public string BHP { get; set; }
[DefaultValue(null)]
public string Year { get; set; }
}
And I display in DataGridView like this:
List<Cars> ret = db.Query<Cars>("select * from cars").ToList();
if(ret != null)
dgv.DataSource = ret; // .OrderBy(o => o.Year).ToList();
However, seems that DGV put columns like in object (design time) order. I could alter this by using a loop with DGV DisplayIndex property but there is a simple solution, some attribute decorate?
Thanks in advance,
PS. I tried also using System.ComponentModel.DataAnnotations but seems that for WinForms isn't working. The DGV isn't able to bind that attributes.
[Display(Name = "Custom Name", Order = 2)]
Any hack? Thanks very much.
Thanks to Tim Van Wassenhove's elegant solution, I managed to do exactly what I wanted.
http://www.timvw.be/2007/02/04/control-the-order-of-properties-in-your-class/
It requires a modified BindingList<> class (I modified a bit more)
[AttributeUsage(AttributeTargets.Property)]
public class PropertyOrderAttribute : Attribute
{
private int order;
public PropertyOrderAttribute(int order)
{
this.order = order;
}
public int Order
{
get { return this.order; }
}
}
class PropertyOrderBindingList<T> : BindingList<T>, ITypedList
{
public PropertyOrderBindingList(List<T> list)
: base(list)
{
//
}
public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
{
PropertyDescriptorCollection typePropertiesCollection = TypeDescriptor.GetProperties(typeof(T));
return typePropertiesCollection.Sort(new PropertyDescriptorComparer());
}
public string GetListName(PropertyDescriptor[] listAccessors)
{
return string.Format("A list with Properties for {0}", typeof(T).Name);
}
}
class PropertyDescriptorComparer : IComparer
{
public int Compare(object x, object y)
{
if (x == y) return 0;
if (x == null) return 1;
if (y == null) return -1;
PropertyDescriptor propertyDescriptorX = x as PropertyDescriptor;
PropertyDescriptor propertyDescriptorY = y as PropertyDescriptor;
PropertyOrderAttribute propertyOrderAttributeX = propertyDescriptorX.Attributes[typeof(PropertyOrderAttribute)] as PropertyOrderAttribute;
PropertyOrderAttribute propertyOrderAttributeY = propertyDescriptorY.Attributes[typeof(PropertyOrderAttribute)] as PropertyOrderAttribute;
if (propertyOrderAttributeX == propertyOrderAttributeY) return 0;
if (propertyOrderAttributeX == null) return 1;
if (propertyOrderAttributeY == null) return -1;
return propertyOrderAttributeX.Order.CompareTo(propertyOrderAttributeY.Order);
}
}
Now, just decorate the poco object attributes with order:
[DefaultValue(null)]
[DisplayName("Column Name")]
[PropertyOrder(3)]
public string Color { get; set; }
[DefaultValue(null)]
[PropertyOrder(1)]
public string Engine { get; set; }
[DefaultValue(null)]
[PropertyOrder(0)]
public string BHP { get; set; }
[DefaultValue(null)]
[PropertyOrder(2)]
public string Year { get; set; }
And query like this
List<Cars> ret2 = db.Query<Cars>("select * from cars").ToList();
PropertyOrderBindingList<Cars> ret = new PropertyOrderBindingList<Cars>(ret2);
The properties will be in custom order.
Im making a new years eve quiz for some friends. The quiz itself is done and working I just thought it would be cool to autocorrect the answers once they are posted.
The question is what's the best way to compare the posted object with an object that has all the right answers, reflection?. There has to be a slick way to do it and avoid having a lot of if's.
public class QuizModel
{
public string Name { get; set; }
public string Quiz1 { get; set; }
public string Quiz2 { get; set; }
public string Quiz3 { get; set; }
etc..
}
You dont have to write me any code. I just want some directions on what the best ( and most important the coolest) way to do it :)
As for your explanation, the implementation of this class should be a list of answers (or a dictionary, or an array, etc):
public class QuizModel
{
public string Name { get; set; }
public List<string> Quizs { get; set; }
}
Then, to check if all the answers are the same:
public bool AreEqual(model1, model2){
for(var i = 0; i < Math.Min(model1.Quizs.Count, model2.Quizs.Count); ++i)
if(model1.Quizs[i] != model2.Quizs[i])
return false;
return true;
}
In a similar way you can get the number of answers that are identical.
You don't need to use reflection to compare values, no :)
If all of the values are encapsulated within a model, then so should be the comparison logic. One simple approach could be to just override .Equals(). Something like this:
public override bool Equals(object obj)
{
if (obj == null)
return false;
if (!(obj is QuizModel))
return false;
var quiz = obj as QuizModel;
return
quiz.Name.Equals(this.Name) &&
quiz.Quiz1.Equals(this.Quiz1) &&
// etc.
}
Of course, that's the easy part. The real challenge is going to be that string comparison logic. Strings sounds like free text input. So if one of the answers is "Christmas Day" then what do you do with inputs like "Christmas day" or "christmas" or "december 25th" and so on? That's up to your business logic. But the actual logic of "are these two objects equal" is pretty straightforward.
Semantically you might choose not to override .Equals() for this purpose. I could see a good argument against it, claiming that the objects are different but simply contain the same values. (A great real world example of this are identical twins.) So you may choose to implement something else, like IEquatable or just a custom method like .IsEqualTo(QuizModel quiz). But the logic therein would be the same either way.
I'm giving you two solutions to your question. I think you want to give scores to your friends(I would do that). If so, here is a solution that give you the score for the answer, I'm supposing that every quiz has the same value and you have the correct answer for all the quiz. First you could try by reflection compare all the values of the quizes, and return total(assuming your quizes have the same value. Then if you want to be more flexible below I suggest you a possible solution when the quizes may have a different value(score).
1)
public class QuizModel
{
public string Name { get; set; }
public string Quiz1 { get; set; }
public string Quiz2 { get; set; }
public string Quiz3 { get; set; }
}
public class QuizComparer
{
public QuizComparer(QuizModel correctOne, IComparer<string> comparer, int quizValue = 1)
{
this.CorrectOne = correctOne;
this.Comparer = comparer;
this.QuizValue = quizValue;
}
public int Compare(QuizModel toCompareOne)
{
Type type = toCompareOne.GetType();
var propertiesInfo = type.GetProperties();
int result = 0;
foreach (var propertyInfo in propertiesInfo)
{
if (propertyInfo.CanRead)
{
var toCompareOnePropertyValue = type.GetProperty(propertyInfo.Name).GetValue(toCompareOne).ToString();
var correctOnePropertyValue = type.GetProperty(propertyInfo.Name).GetValue(this.CorrectOne).ToString();
if (Comparer.Compare(toCompareOnePropertyValue, correctOnePropertyValue) == 0)//equals
{
result += QuizValue;
}
}
}
return result;
}
public QuizModel CorrectOne { get; set; }
public IComparer<string> Comparer { get; set; }
public int QuizValue { get; set; }
}
2) Secondly if you want to give to your quizes individual scores, you could find this very helpful:
public class QuizModel
{
public string Name { get; set; }
[QuizValue(value: 1)]
public string Quiz1 { get; set; }
[QuizValue(value: 2)]
public string Quiz2 { get; set; }
[QuizValue(value: 3)]
public string Quiz3 { get; set; }
}
public class QuizComparer
{
public QuizComparer(QuizModel correctOne, IComparer<string> comparer, int quizValue = 1)
{
this.CorrectOne = correctOne;
this.Comparer = comparer;
this.QuizDefaultValue = quizValue;
}
public int Compare(QuizModel toCompareOne)
{
Type type = toCompareOne.GetType();
var propertiesInfo = type.GetProperties();
int result = 0;
foreach (var propertyInfo in propertiesInfo)
{
if (propertyInfo.CanRead && propertyInfo.Name != "Name")
{
var toCompareOnePropertyValue = type.GetProperty(propertyInfo.Name).GetValue(toCompareOne).ToString();
var correctOnePropertyValue = type.GetProperty(propertyInfo.Name).GetValue(this.CorrectOne).ToString();
int value = GetQuizValue(propertyInfo);
if (Comparer.Compare(toCompareOnePropertyValue, correctOnePropertyValue) == 0)//equals
{
result += value;
}
}
}
return result;
}
private int GetQuizValue(PropertyInfo propertyInfo)
{
var attributes = propertyInfo.GetCustomAttributes(typeof(QuizValue), false);
int value = this.QuizDefaultValue;
if (attributes != null && attributes.Count() > 0)
{
var quizValueAttribute = attributes[0];
if (quizValueAttribute is QuizValue)
{
var quizValue = quizValueAttribute as QuizValue;
value = quizValue.Value;
}
}
return value;
}
public QuizModel CorrectOne { get; set; }
public IComparer<string> Comparer { get; set; }
public int QuizDefaultValue { get; set; }
}
[System.AttributeUsage(System.AttributeTargets.Property)]
public class QuizValue : System.Attribute
{
public QuizValue(int value = 1)
{
this.Value = value;
}
public int Value
{
get;
set;
}
}
Please try like below, May this will leads you to get what you think
It will always compare the Quiz2 with the Quiz1 value.
public string Quiz1 {get; set;}
[CompareAttribute("Quiz1", ErrorMessage = "Quiz2 is mismatch with Quiz1")]
public string Quiz2 { get; set; }
this will give you wrong answers only:
var quiz = new QuizModel() { Name = "Quiz 1", Quiz1 = "Correct answer", Quiz2 = "Correct answer", Quiz3 = "Correct answer" };
var correctQuiz = new QuizModel() { Name = "Quiz 1", Quiz1 = "Correct answer", Quiz2 = "Wrong answer", Quiz3 = "Wrong answer 2" };
Func<QuizModel, List<string>> getListOfAnswers = (currentquiz) =>
(
from property
in typeof(QuizModel).GetProperties()
select property.Name + " " + property.GetValue(currentquiz)
).ToList();
var answers = getListOfAnswers(quiz);
var correctAnswers = getListOfAnswers(correctQuiz);
var wrongAnswers = correctAnswers.Except(answers);
output:
Quiz2 Wrong answer
Quiz3 Wrong answer 2
This solution is using Reflection, LINQ and Anonymous functions at once so it's very cool :)