Получите общий метод, не используя GetMethods

Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.

Например, ниже - класс ученика, который будет использовать его в нашем коде.

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Приведенный ниже код дает вам исключение с нулевым указателем.

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}

Поскольку вы используете Obj_Student, но вы забыли инициализировать его, как в правильном коде, показанном ниже:

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student = new Student();
            obj_Student.setId(12);
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}
26
задан abatishchev 8 December 2016 в 21:16
поделиться

5 ответов

Решенный (путем взламывания LINQ)!

я видел Ваш вопрос при исследовании той же проблемы. После нахождения никакого хорошего решения у меня была идея посмотреть на дерево выражений LINQ. Вот то, что я придумал:

public static MethodInfo GetOrderByMethod<TElement, TSortKey>()
{
    Func<TElement, TSortKey> fakeKeySelector = element => default(TSortKey);

    Expression<Func<IEnumerable<TElement>, IOrderedEnumerable<TElement>>> lamda
        = list => list.OrderBy(fakeKeySelector);

    return (lamda.Body as MethodCallExpression).Method;
}

static void Main(string[] args)
{
    List<int> ints = new List<int>() { 9, 10, 3 };
    MethodInfo mi = GetOrderByMethod<int, string>();           
    Func<int,string> keySelector = i => i.ToString();
    IEnumerable<int> sortedList = mi.Invoke(null, new object[] { ints, 
                                                                 keySelector }
                                           ) as IEnumerable<int>;

    foreach (int i in sortedList)
    {
        Console.WriteLine(i);
    }
}

вывод: 10 3 9

РЕДАКТИРОВАНИЕ: Вот то, как получить метод, если Вы не знаете тип во время компиляции:

public static MethodInfo GetOrderByMethod(Type elementType, Type sortKeyType)
{
    MethodInfo mi = typeof(Program).GetMethod("GetOrderByMethod", Type.EmptyTypes);

    var getOrderByMethod = mi.MakeGenericMethod(new Type[] { elementType,
                                                             sortKeyType });
    return getOrderByMethod.Invoke(null, new object[] { }) as MethodInfo;
}

убедиться заменить typeof (Программа) typeof (WhateverClassYouDeclareTheseMethodsIn).

21
ответ дан Noctis 28 November 2019 в 07:12
поделиться

Вариант Вашего решения, как дополнительный метод:

public static class TypeExtensions
{
    private static readonly Func<MethodInfo, IEnumerable<Type>> ParameterTypeProjection = 
        method => method.GetParameters()
                        .Select(p => p.ParameterType.GetGenericTypeDefinition());

    public static MethodInfo GetGenericMethod(this Type type, string name, params Type[] parameterTypes)
    {
        return (from method in type.GetMethods()
                where method.Name == name
                where parameterTypes.SequenceEqual(ParameterTypeProjection(method))
                select method).SingleOrDefault();
    }
}
13
ответ дан Jon Skeet 28 November 2019 в 07:12
поделиться

Я не полагаю, что существует простой способ сделать это - это - в основном недостающая возможность от отражения, IIRC. Необходимо циклично выполниться через методы для нахождения того, который Вы хотите: (

4
ответ дан Jon Skeet 28 November 2019 в 07:12
поделиться
var orderBy =
        (from methodInfo in typeof(System.Linq.Queryable).GetMethods()
         where methodInfo.Name == "OrderBy"
         let parameterInfo = methodInfo.GetParameters()
         where parameterInfo.Length == 2
         && parameterInfo[0].ParameterType.GetGenericTypeDefinition() == typeof(IQueryable<>)
         && parameterInfo[1].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>)
         select
            methodInfo
        ).Single();
2
ответ дан Dave 28 November 2019 в 07:12
поделиться

Используя лямбда-выражения, вы можете легко получить общий метод

    var method = type.GetGenericMethod
            (c => c.Validate((IValidator<object>)this, o, action));

Подробнее об этом здесь:

http://www.nerdington.com/2010/08/calling-generic-method-without-magic.html

http://web.archive.org/web/20100911074123/http://www.nerdington.com/2010/08/calling-generic-method-without-magic.html

1
ответ дан 28 November 2019 в 07:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: