如何使字段仅在扩展方法内可设置

How to make a field set-able only inside extension method

您好,我希望能够仅在 extension 方法中设置对象字段的 a。我希望这个字段要么是完全私有的,要么只是 get-来自外部的:

public class Myclass
{
   private int Value{get;set;}
}
public static class Ext
{
   public Myclass SetValue(this Myclass obj,int val)
   {
       this.obj.Value=val;
       return obj;
   }
}

正如您在上面的示例中看到的那样,我必须声明 Value public 才能在扩展中访问它,如果我可以创建变量,我会同意的只有get-able来自外面。

我需要此功能,因为我想开发类似 fluent api 的东西,您只能在其中使用扩展设置一些变量。

例如:

      a=new Myclass();
      a.SetValue1(1).SetValue2(2);//--some code //--a.SetValue3(3);

你想让它用扩展方法来做,但在这种情况下你不能。

你最好的选择是

public class Myclass
{
   public int Value{get; private set;}

   public Myclass SetValue(int val)
   {
       this.Value=val;

       return obj;
   }
}

听起来您使用的工具不对,扩展方法无法访问非 public 成员。

您想要的行为仅限于实例方法或属性。我的建议是将实例方法添加到 class.

如果这还不能说服您,那么您可以改用反射来更新私有实例变量:

public static class Ext
{
    public Myclass SetValue(this Myclass obj,int val)
    {
        var myType = typeof(Myclass);

        var myField = myType.GetField("Value", BindingFlags.NonPublic | BindingFlags.Instance);

        myField.SetValue(obj, val);

        return obj;
   }
}

请注意,这有以下陷阱:

  1. 如果您决定重命名字段 Value,则没有编译时检查来拯救您。 (虽然单元测试可以保护你)
  2. 反射通常比常规实例方法慢得多。 (尽管如果不经常调用此方法,性能可能无关紧要)