Невозможно получить доступ к переменной экземпляра с помощью метода расширения с помощью лямбды
Я создал метод расширения в соответствии с ответом на SO здесь
public class AcObject
{
public int Id { get; set; }
}
public static Dictionary<string, string> GetValidationList<AcObject, TProperty>(
this AcObject source,
Expression<Func<AcObject, TProperty>> propertyLambda)
{
// Autocomplete here only shows static members for 'source'
// I am expecting to be able to do source.Id
}
Любой, кто может объяснить мне, почему я не могу использовать source.Id
в приведенном выше сценарии и предложите, где я могу найти подобное решение?
Если я установлю точку останова внутри GetValidationList()
метод я могу навести курсор мыши на источник и увидеть экземпляр и его свойства, как и следовало ожидать... я просто не могу использовать его в VS.
Моя общая цель - сделать следующее
public class AcObject
{
public int Id { get; set; }
public string Type { get; set; }
}
public class OtherObject : AcObject
{
public string AssetTag { get; set; }
}
// somewhere else in code
AcObject myObject = new AcObject();
myObject.GetValidationList(a => a.Type);
// Along with using the type that inherits it
OtherObject myOtherObject = new OtherObject();
myOtherObject.GetValidationList(a => a.Type);
// In some kind of extension method lambda magic
{
Console.WriteLine(source.Id);
}
Редактировать - Обновлено, чтобы включить требование, чтобы оно работало с базовыми классами, а также с теми, которые его наследуют.
2 ответа
Измените подпись вашего метода расширения следующим образом: (удалите начальный "AcObject")
public static Dictionary<string, string> GetValidationList<TProperty>(
this AcObject source, Expression<Func<AcObject, TProperty>> propertyLambda)
В вашем последнем фрагменте кода есть опечатка:
AcObject myObject = new AcObject();
myObject.GetValidationList(a => a.Type); // call the extension method on the instance
Те параметры типа, которые вы включили (AcObject и TProperty), являются заполнителями, представляющими фактические типы, которые вы указываете при вызове метода. Называя первый "AcObject" в вашем методе, вы скрываете фактический класс, также называемый "AcObject" (поэтому "AcObject" в this AcObject source
больше не ссылается на ваш класс).
Обновив свой вопрос, измените свою подпись следующим образом. Вначале вы правильно сделали, просто измените имя параметра типа с "AcObject" на другое, отличное от имени вашего класса, например "T":
public static Dictionary<string, string> GetValidationList<T, TProperty>(
this T source, Expression<Func<T, TProperty>> propertyLambda)
Тогда вы можете назвать это с вашими различными классами:
AcObject myObject = new AcObject();
myObject.GetValidationList(a => a.Id);
OtherObject myOtherObject = new OtherObject();
myOtherObject.GetValidationList(a => a.AssetTag);
public static class stat
{
public static void GetValidationList( this AcObject source )
{
Console.WriteLine(source.Id);
}
}
public class AcObject
{
public int Id { get; set; }
}
Использование:
AcObject myObject = new AcObject();
myObject.GetValidationList();