यहाँ एक दिलचस्प मुद्दा जब Except
ऑपरेटर का उपयोग कर मैंने देखा है: मैं उपयोगकर्ताओं की सूची है जिसमें से मैं कुछ उपयोगकर्ताओं को बाहर निकालना चाहते:LINQ छोड़कर ऑपरेटर और वस्तु समानता
उपयोगकर्ताओं की सूची एक एक्सएमएल से आ रही है फ़ाइल:
कोड इस प्रकार है:
interface IUser
{
int ID { get; set; }
string Name { get; set; }
}
class User: IUser
{
#region IUser Members
public int ID
{
get;
set;
}
public string Name
{
get;
set;
}
#endregion
public override string ToString()
{
return ID + ":" +Name;
}
public static IEnumerable<IUser> GetMatchingUsers(IEnumerable<IUser> users)
{
IEnumerable<IUser> localList = new List<User>
{
new User{ ID=4, Name="James"},
new User{ ID=5, Name="Tom"}
}.OfType<IUser>();
var matches = from u in users
join lu in localList
on u.ID equals lu.ID
select u;
return matches;
}
}
class Program
{
static void Main(string[] args)
{
XDocument doc = XDocument.Load("Users.xml");
IEnumerable<IUser> users = doc.Element("Users").Elements("User").Select
(u => new User
{ ID = (int)u.Attribute("id"),
Name = (string)u.Attribute("name")
}
).OfType<IUser>(); //still a query, objects have not been materialized
var matches = User.GetMatchingUsers(users);
var excludes = users.Except(matches); // excludes should contain 6 users but here it contains 8 users
}
}
जब मैं User.GetMatchingUsers(users)
फोन की उम्मीद के रूप में मैं 2 मैच मिलता है। मुद्दा यह है कि जब मैं users.Except(matches)
पर कॉल करता हूं तो मेल खाने वाले उपयोगकर्ताओं को बिल्कुल बाहर नहीं रखा जा रहा है! मैं उम्मीद कर रहा हूं कि 6 उपयोगकर्ताओं को "बहिष्कृत" करने के बजाय सभी 8 उपयोगकर्ता शामिल हैं।
के बाद से सभी मैं GetMatchingUsers(IEnumerable<IUser> users)
में कर रहा हूँ IEnumerable<IUser>
ले जा रहा है और सिर्फ लौटने IUsers
जिसकी आईडी के मैच (इस मामले में 2 IUsers), मैं समझता हूँ कि डिफ़ॉल्ट रूप से Except
वस्तुओं की तुलना के लिए संदर्भ समानता प्रयोग करेंगे बाहर रखा जाना चाहिए। क्या यह Except
व्यवहार नहीं करता है?
क्या और भी दिलचस्प है कि अगर मैं .ToList()
का उपयोग कर वस्तुओं अमल में लाना और फिर मिलान उन मिलता है, और Except
फोन, सब कुछ उम्मीद के रूप में काम करता है!
:
IEnumerable<IUser> users = doc.Element("Users").Elements("User").Select
(u => new User
{ ID = (int)u.Attribute("id"),
Name = (string)u.Attribute("name")
}
).OfType<IUser>().ToList(); //explicity materializing all objects by calling ToList()
var matches = User.GetMatchingUsers(users);
var excludes = users.Except(matches); // excludes now contains 6 users as expected
मैं नहीं दिख रहा है कारण है कि मैं Except
बुला दिया है कि इसके IEnumerable<T>
पर परिभाषित के लिए वस्तुओं अमल में लाना करने की जरूरत है चाहिए?
किसी भी सुझाव/अंतर्दृष्टि की सराहना की जाएगी।
यदि ऐसा है, तो क्या "नई" ऑब्जेक्ट्स को GetMatchingUsers में हर बार पारित नहीं किया जाएगा? यह भी विधि परिणाम के रूप में एक क्वेरी देता है और वस्तुओं नहीं। बस मेरे 2 सेंट ... –
नहीं, क्योंकि जब भी इसका उपयोग किया जाता है तो अभिव्यक्ति का मूल्यांकन किया जाता है। मेरे कोड में, जो यह दिखाता है, इसे GetMatchingUsers पर कॉल करने से पहले मेरे आउटपुट द्वारा मूल्यांकन किया जाता है, फिर फिर GetMatchingUSers को कॉल करते समय, और महत्वपूर्ण रूप से, फिर से छोड़कर। –
क्योंकि GetMatchingUsers के मूल्यांकन और दोनों को छोड़कर अपने स्वयं के उदाहरण उत्पन्न करते हैं, वैसे ही आप अपेक्षा करते हुए कार्य करने में विफल रहते हैं। –