无法使用带有Lambda的扩展方法访问实例变量

时间:2014-09-24 05:16:57

标签: c# linq lambda extension-methods

我根据答案on SO here

创建了一个扩展方法
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
}

enter image description here

任何人都能向我解释为什么我不能在上述情况下使用source.Id并建议我在哪里提出类似的解决方案?

如果我在GetValidationList()方法中设置了一个断点,我可以将鼠标悬停在源代码中,看看实例及其属性,就像人们期望的那样......我只是不能在VS中使用它。

enter image description here

我的总体目标是能够执行以下操作

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 个答案:

答案 0 :(得分:4)

更改扩展方法的签名,如下所示:(删除初始的“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”(因此this AcObject source中的“AcObject”不再引用您的类)。


鉴于您的问题更新,请修改您的签名。你基本上在开始时把它更正,只需将类型参数的名称从“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);

答案 1 :(得分:0)

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();