【问题标题】:Unable to access instance variable with an Extension Method with Lambda无法使用 Lambda 的扩展方法访问实例变量
【发布时间】:2014-09-24 05:16:56
【问题描述】:

我根据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
}

谁能向我解释为什么我不能在上述场景中使用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);
}

编辑 - 更新以包括它在基类以及继承它的那些上工作的要求。

【问题讨论】:

    标签: c# linq lambda extension-methods


    【解决方案1】:

    改变你的扩展方法的签名如下:(去掉初始的“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);
    

    【讨论】:

    • 很高兴解释为什么 OP 需要更改签名。看起来他误解了类型参数的概念。
    • 正如@Dennis 提到的,我认为我在这里误解了一些东西。如果我按照您提到的那样进行上述更改,那么它对于显式为AcObject 的任何对象都可以正常工作,但对于继承AcObject 的对象则失败。我将修改我的 OP 以包含一个示例。
    • 明确地说,“失败”是指它仅在我的 lamda 表达式中列出 AcObject 的属性,而不是当前类型的属性。 public class AcAsset : AcObject { ... } 然后AcAsset asset = new AcAsset().GetValidationList(a =&gt; a. 这里只列出了AcObject的成员
    【解决方案2】:
    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();
    

    【讨论】:

    • 感谢您的及时回答,但我正在寻找包含 lamda 表达式的内容。
    猜你喜欢
    • 2021-09-22
    • 1970-01-01
    • 2012-01-10
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多