2011-03-15 15 views
39

मैं प्रो एमवीसी 2 पुस्तक पढ़ रहा हूं, और HtmlHelper क्लास के लिए एक एक्सटेंशन विधि बनाने का एक उदाहरण है।क्या कोई बता सकता है कि सी # "Func <T,T>" क्या करता है?

यहाँ कोड उदाहरण:

[Test] 
public void Can_Generate_Links_To_Other_Pages() 
{ 
    //Arrange: We're going to extend the Html helper class. 
    //It doesn't matter if the variable we use is null    
    HtmlHelper html = null; 

    PagingInfo pagingInfo = PagingInfo(){ 
     CurrentPage = 2, 
     TotalItems = 28, 
     ItemsPerPage = 10 
    }; 

    Func<int, String> pageUrl = i => "Page" + i; 

    //Act: Here's how it should format the links. 
    MvcHtmlString result = html.PageLinks(pagingInfo, pageUrl); 

    //Assert: 
    result.ToString().ShouldEqual(@"<a href=""Page1"">1</a><a href=""Page2"">2</a><a href=""Page3"">3</a>")   

} 

संपादित करें:: निकाला बात यह है कि इस सवाल का बिंदु उलझन

public static MvcHtmlString PageLinks(this HtmlHelper html, PagingInfo pagingInfo, Func<int,string> pageUrl) 
{ 
    //Magic here. 
} 

और यहाँ एक उदाहरण उपयोग है।

सवाल यह है: Func का उपयोग करने का उदाहरण क्यों है? मुझे इसका उपयोग कब करना चाहिए? Func क्या है?

धन्यवाद!

+0

मुख्य रूप से एक प्रतिनिधि है देखेंगे, मैं जानना चाहते हैं कि क्या समारोह PAGEURL = मैं => "पृष्ठ 1" + मैं; लाइन कर रही है –

+1

मुझे समझ में नहीं आता है। 'Func 'का विस्तार विधियों से कोई लेना देना नहीं है। आप क्या पूछ रहे हो? – BoltClock

+0

क्या आपका मतलब 'पेजलिंक्स' की घोषणा है? पहला पैरामीटर 'यह' है, यानी यह एक विस्तार विधि है। वह पैरामीटर कॉल में 'html' ऑब्जेक्ट से बाध्य हो जाता है। – Pete

उत्तर

105

एक Func<int, string> तरह

Func<int, String> pageUrl = i => "Page" + i; 

एक प्रतिनिधि int अपने एकमात्र पैरामीटर के रूप में स्वीकार करने और एक string लौटने है। इस उदाहरण में, यह int पैरामीटर को i नाम से स्वीकार करता है और स्ट्रिंग "Page" + i देता है जो स्ट्रिंग "Page" पर i के मानक स्ट्रिंग प्रस्तुति को जोड़ता है।

सामान्य रूप से, Func<TSource, TResult>TSource प्रकार का एक पैरामीटर स्वीकार करता है और TResult प्रकार का पैरामीटर देता है। उदाहरण के लिए,

Func<string, string> toUpper = s => s.ToUpper(); 

तो आप कह सकते हैं

string upper = toUpper("hello, world!"); 

या

Func<DateTime, int> month = d => d.Month; 

तो आप कह सकते हैं

int m = month(new DateTime(3, 15, 2011)); 
1

क्योंकि PageLinks विधि Extension Method है।

विस्तार विधि में, पहला पैरामीटर इस कीवर्ड के साथ शुरू होता है यह इंगित करने के लिए कि यह पहले पैरामीटर द्वारा प्रदर्शित प्रकार पर एक एक्सटेंशन विधि है।

Func<T1, T2> एक प्रतिनिधि है जो T1 से T2 टाइप करने के लिए एक रूपांतरण का प्रतिनिधित्व करता है। तो मूल रूप से, विधि पर string का उत्पादन करने के लिए उस परिवर्तन को लागू करेगी।

+1

ठीक है - लेकिन Func भाग के बारे में क्या? –

+0

Func के लिंक के लिए मेरा उत्तर देखें। –

13

Func<int, String> का अर्थ है कॉलबैक विधि जो int पैरामीटर लेती है और परिणामस्वरूप String देता है।

निम्नलिखित अभिव्यक्ति है, जो एक lambda expression के रूप में जाना जाता है:

Func<int, String> pageUrl = i => "Page" + i; 

कुछ इस तरह के लिए विस्तारित:

Func<int, String> pageUrl = delegate(int i) 
{ 
    return "Page" + i; 
} 
3

Func<int, string> लाइन है कि आप के बारे में एक लैम्ब्डा अभिव्यक्ति के रूप में जाना जाता है पूछताछ कर रहे हैं।

Func<int, String> pageUrl = i => "Page" + i; 

यह पंक्ति एक समारोह है कि एक पूर्णांक पैरामीटर (i) लेता है और एक स्ट्रिंग "Page" + i रिटर्न के रूप में वर्णित किया जा सकता है;

यह रूप में फिर से लिखा जा सकता है:

delegate(int i) 
{ 
    return "Page" + i; 
} 
+0

क्या प्रतिनिधियों को अधिभारित करना संभव है, कहें कि इनपुट एक सामान्य टी था जहां टी: कक्षा? –

1

Func<T, TResult>: एक विधि एक पैरामीटर है कि समाहित और retur ns TResult पैरामीटर द्वारा निर्दिष्ट प्रकार का मान। See this page for more details और उदाहरण। :-)

0

मैं समारोह कृपया एक नजर है का उपयोग कर एक जहां() विस्तार विधि को लागू किया है ...

public static IEnumerable<Tsource> Where<Tsource> (this IEnumerable<Tsource> a , Func<Tsource , bool> Method) 
{ 

    foreach (var data in a) 
    { 
     //If the lambda Expression(delegate) returns "true" Then return the Data. (use 'yield' for deferred return) 
     if (Method.Invoke (data)) 
     { 
      yield return data; 
     } 
    } 
} 

आपको इस तरह उपयोग कर सकते हैं,

 foreach (var item in Emps.Where (e => e.Name == "Shiv").Select (e1 => e1.Name)) 
     { 
      Console.WriteLine (item); 
     } 
1

पर एक ब्लॉग पोस्ट है इस। Func का उपयोग करके आप कुछ कार्यात्मक विसंगति को हल कर सकते हैं। here पढ़ें।

0

अपनी खुद की

Func<int,string> myfunc; 

तो सही देखने के लिए क्लिक करें समारोह परिभाषा बनाएं। आप इसे underneith

public delegate TResult Func<in T, out TResult>(T arg); 
संबंधित मुद्दे