سؤال

ولدي البرمجية التالية:

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<TClass, TMember>(Expression<Func<TClass, TMember>> expr)
    {

    }
}

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

    public String Name { get; set; }
}

وأحصل على رسالة خطأ المترجم هذا:

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

إذا قمت بتغيير الدعوة إلى FigureItOut لهذه:

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

وبعد ذلك يعمل. هل هناك طريقة للحصول على المثال الأول لتجميع عن طريق تغيير الفئة الأساسية بدلا من ذلك؟

وأنا أعلم أنني إذا جعل الطبقة قاعدة كامل عام، مثل هذا:

public class Base<TDescendant>
{
    protected void FigureItOut<TMember>(Expression<Func<TDescendant, TMember>> expr)
    {

    }
}

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

    public String Name { get; set; }
}

وبعد ذلك يعمل، ولكن أنا أفضل أن لا يفعل ذلك، أي الخارقة الأخرى التي يمكن استخدامها، وربما على مستوى طريقة (أي تغير FigureItOut بطريقة أو بأخرى).

هل كانت مفيدة؟

المحلول

وماذا عن طريقة تمديد الذي يستدعي (protected internal) التنفيذ الفعلي؟ الجانب السلبي الوحيد هو أن يكون لديك لإضافة this..

ويعمل هذا لأن المعلمة source (عبر this) تستدل على نوع لTClass.

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

public static class BaseExt
{
    public static void FigureItOut<TClass, TMember>(this TClass source, Expression<Func<TClass, TMember>> 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; }
}

وكبديل (إذا كان internal هو الألم)، والنظر في جعله ثابت، مع وسيطة المثيل الذي يستخدم في المقام الأول لنوع الاستدلال:

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

}

public void TestMethod()
{
    FigureItOut(this, c => c.Name);
}

نصائح أخرى

وإذا لم يستغرق معلمة، فإنه غير قادر على الاستدلال. ما لم يعين قيمة الإرجاع، فإنه غير قادر على الاستدلال.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top