विरासत के दौरान अभिव्यक्ति अनुमान

मेरे पास निम्न कोड है:

using System;
using System.Linq;
using System.Linq.Expressions;

public class Program
{
    public static void Main()
    {
        Descendant d = new Descendant();
        d.TestMethod();
    }
}

public class Base
{
    protected void FigureItOut(Expression> expr)
    {

    }
}

public class Descendant : Base
{
    public void TestMethod()
    {
        FigureItOut(c => c.Name);
    }

    public String Name { get; set; }
}

मुझे यह कंपाइलर त्रुटि संदेश मिलता है:

The type arguments for method
'Base.FigureItOut 
(System.Linq.Expressions.Expression>)'
cannot be inferred from the usage. Try specifying the type arguments explicitly.

अगर मैं इस पर चित्रा ITOut को कॉल बदलता हूं:

FigureItOut((Descendant c) => c.Name);

फिर यह काम करता है। इसके बजाय बेस क्लास को बदलकर संकलित करने का पहला उदाहरण प्राप्त करने का कोई तरीका है?

मुझे पता है कि अगर मैं पूरी बेस क्लास जेनेरिक बनाता हूं, तो इस तरह:

public class Base<tdescendant>
{
    protected void FigureItOut(Expression> expr)
    {

    }
}

public class Descendant : Base
{
    public void TestMethod()
    {
        FigureItOut(c => c.Name);
    }

    public String Name { get; set; }
}

फिर यह काम करता है, लेकिन मैं ऐसा नहीं करता, किसी अन्य हैक्स को नियोजित किया जा सकता है, शायद विधि स्तर पर (यानी किसी भी तरह से चित्रा ItOut बदलें)।

0
मैंने एक विकल्प जोड़ा है जो आंतरिक आवश्यकता (और एक्सटेंशन विधि) से बचाता है
जोड़ा लेखक Marc Gravell, स्रोत

2 उत्तर

जब तक यह एक पैरामीटर नहीं लेता है, इसे अनुमानित नहीं किया जा सकता है। जब तक यह एक वापसी मूल्य निर्दिष्ट नहीं करता है, इसे अनुमानित नहीं किया जा सकता है।

0
जोड़ा
एएच हाँ, यह सच है :)
जोड़ा लेखक leppie, स्रोत
यह मत भूलना कि arg0 (उर्फ "यह") भी एक पैरामीटर है जो विशेष रूप से एक्सटेंशन विधियों के माध्यम से टाइप अनुमान को ड्राइव कर सकता है।
जोड़ा लेखक Marc Gravell, स्रोत

एक एक्सटेंशन विधि के बारे में जो वास्तविक ( संरक्षित आंतरिक ) कार्यान्वयन को कॉल करता है? केवल नकारात्मक पक्ष आपको यह जोड़ना होगा।

यह काम करता है क्योंकि स्रोत पैरामीटर ( यह के माध्यम से) TClass के लिए एक प्रकार का अनुमान लगाता है।

public class Base
{
    protected internal void FigureItOut(Expression> expr)
    {
        Debug.WriteLine("Got to actual method");
    }
}

public static class BaseExt
{
    public static void FigureItOut(this TClass source, Expression> expr)
        where TClass : Base
    {//call the actual method
        Debug.WriteLine("Got to extension method");
        source.FigureItOut(expr);
    }
}
public class Descendant : Base
{
    public void TestMethod()
    {
        this.FigureItOut(c => c.Name);
    }

    public String Name { get; set; }
}

एक विकल्प के रूप में (यदि आंतरिक दर्द होता है), इसे स्थिर बनाने पर विचार करें, उदाहरण के तर्क के साथ मुख्य रूप से टाइप अनुमान के लिए उपयोग किया जाता है:

protected static void FigureItOut(TClass source, Expression> expr)
{

}

public void TestMethod()
{
    FigureItOut(this, c => c.Name);
}
0
जोड़ा
हम्म, यह एक और समस्या हल करता है, जो कुछ हीरे के आकार की विरासत की समस्या से संबंधित है, लेकिन यह बाहरी लोगों को चित्राइटऑट विधि का भी खुलासा करता है, हमें यह विचार करना होगा कि क्या वह व्यापार है जिसके साथ हम रह सकते हैं।
जोड़ा लेखक Lasse Vågsæther Karl, स्रोत
समस्या यह है, और पता है कि मैंने इस सवाल में यह नहीं बताया है, लेकिन बेस क्लास कक्षा पुस्तकालय में है, और वंशज दूसरे में है, या एक आवेदन परियोजना में है, इसलिए यहां कुछ समस्याएं हैं
जोड़ा लेखक Lasse Vågsæther Karl, स्रोत
@lassevk - ठीक है, आंतरिक बाहरी ... ध्यान दें कि आप बेसएक्स आंतरिक भी बना सकते हैं ...
जोड़ा लेखक Marc Gravell, स्रोत
@lassevk - उस स्थिति में, बेस पर केवल एक संरक्षित स्थैतिक विधि पर विचार करें जो पहले तर्क के रूप में एक उदाहरण स्वीकार करता है, और FigItOut (यह, c => c.Name) का उपयोग करें - लगभग उतना ही अच्छा।
जोड़ा लेखक Marc Gravell, स्रोत