यह C # 7.0 है जो स्थानीय कार्यों का समर्थन करता है ...।
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
{
if (source == null) throw new
ArgumentNullException(nameof(source));
if (keySelector == null) throw
new ArgumentNullException(nameof(keySelector));
// This is basically executing _LocalFunction()
return _LocalFunction();
// This is a new inline method,
// return within this is only within scope of
// this method
IEnumerable<TSource> _LocalFunction()
{
var knownKeys = new HashSet<TKey>(comparer);
foreach (var element in source)
{
if (knownKeys.Add(keySelector(element)))
yield return element;
}
}
}
करंट C # के साथ Func<T>
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
{
if (source == null) throw new
ArgumentNullException(nameof(source));
if (keySelector == null) throw
new ArgumentNullException(nameof(keySelector));
Func<IEnumerable<TSource>> func = () => {
var knownKeys = new HashSet<TKey>(comparer);
foreach (var element in source)
{
if (knownKeys.Add(keySelector(element)))
yield return element;
}
};
// This is basically executing func
return func();
}
ट्रिक है, _ () का उपयोग करने के बाद घोषित किया जाता है, जो पूरी तरह से ठीक है।
स्थानीय कार्यों का प्रतीकात्मक उपयोग
उपरोक्त उदाहरण इनलाइन पद्धति का उपयोग कैसे किया जा सकता है इसका सिर्फ एक प्रदर्शन है, लेकिन सबसे अधिक संभावना है कि अगर आप सिर्फ एक बार विधि को लागू करने जा रहे हैं, तो इसका कोई फायदा नहीं है।
लेकिन ऊपर दिए गए उदाहरण में, जैसा कि फूली और लुआण द्वारा टिप्पणियों में उल्लेख किया गया है , स्थानीय फ़ंक्शन का उपयोग करने का एक फायदा है। चूंकि उपज वापसी के साथ कार्य निष्पादित नहीं किया जाएगा, जब तक कि कोई इसे पुनरावृत्त नहीं करता है, इस मामले में स्थानीय फ़ंक्शन के बाहर विधि को निष्पादित किया जाएगा और पैरामीटर सत्यापन भी किया जाएगा, भले ही कोई भी मूल्य को पुनरावृत्त नहीं करेगा।
कई बार हमने विधि में कोड दोहराया है, इस उदाहरण को देखें।
public void ValidateCustomer(Customer customer){
if( string.IsNullOrEmpty( customer.FirstName )){
string error = "Firstname cannot be empty";
customer.ValidationErrors.Add(error);
ErrorLogger.Log(error);
throw new ValidationError(error);
}
if( string.IsNullOrEmpty( customer.LastName )){
string error = "Lastname cannot be empty";
customer.ValidationErrors.Add(error);
ErrorLogger.Log(error);
throw new ValidationError(error);
}
... on and on...
}
मैं इसके साथ अनुकूलन कर सकता है ...
public void ValidateCustomer(Customer customer){
void _validate(string value, string error){
if(!string.IsNullOrWhitespace(value)){
// i can easily reference customer here
customer.ValidationErrors.Add(error);
ErrorLogger.Log(error);
throw new ValidationError(error);
}
}
_validate(customer.FirstName, "Firstname cannot be empty");
_validate(customer.LastName, "Lastname cannot be empty");
... on and on...
}
return _(); IEnumerable<TSource> _()
:?