Reputation: 12192
I have a class ApprovalTicket that has a property called ApprovalRules that is of type IApproval:
IApproval ApprovalRules;
This field will contain several different types of classes that implement that interface. Now stepping one level up, I will have a List of ApprovalTickets. What I'm trying to do is use linq to return a list of ApprovalTickets that have ApprovalRules of the type MocReviewerApproval.
I was trying something like:
var reviews = request.MocApprovalTasks
.Where(mocApproval => mocApproval.ApprovalRules is MocReviewerApproval)
.ToList();
But when I check the list that gets returned, it's still including tickets that have an ApprovalRules type of MocManagerApproval and others as well. What am I missing?
UPDATE:
Let me be more specific. Here is the inheritance scheme
MocApproval : TaskTicket
>>IApproval ApprovalRules;
MocReviewerApproval : IApproval
MocManagerApproval : IApproval
MocControllerApproval : IApproval
internal interface IApproval
{
bool Approve(Guid approverGuid, MocApproval approval);
bool Deny(Guid approverGuid, MocApproval approval, TaskComment denialComment);
bool Close(Guid approverGuid, MocApproval approval, TaskComment closeComment);
bool Notify();
void Set(MocApproval approval);
User GetAssignee();
TaskComment GetNotificationComment();
}
Upvotes: 0
Views: 78
Reputation: 203842
is
means, can be validly cast to, not, "is exactly this type". In your case, any sub-classes of MocReviewerApproval
will still return true. You can use:
mocApproval.ApprovalRules.GetType() == typeof(MocReviewerApproval)
to ensure that that type, and only that type, will return true. Having said that, it's kinda bad code smell to have something like this. Consider asking yourself if that's really what you want.
Upvotes: 2
Reputation: 1500825
Your code looks fine to me. I suspect you've got diagnostic problems, or you're not after the is
kind of relationship at all. Here's a complete example showing it working:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Foo
{
public object Value { get; set; }
}
class Test
{
static void Main()
{
var list = new List<Foo>
{
new Foo { Value = "" },
new Foo { Value = 10 },
new Foo { Value = new object() },
new Foo { Value = new MemoryStream() }
};
ShowCount<IDisposable>(list); // 1 (MemoryStream)
ShowCount<IFormattable>(list); // 1 (Int32)
ShowCount<IComparable>(list); // 1 (String, Int32)
}
static void ShowCount<T>(List<Foo> list)
{
var matches = list.Where(f => f.Value is T)
.ToList();
Console.WriteLine("{0} matches for {1}",
matches.Count, typeof(T));
}
}
EDIT: If you want matches which are exactly the given type, use:
var reviews = request.MocApprovalTasks
.Where(task => task.ApprovalRules.GetType() ==
typeof(MocReviewerApproval))
.ToList();
That's more refactoring-friendly than finding the name as per Servy's original answer.
Upvotes: 1