如何使字段只能在扩展方法内部设置

时间:2019-03-09 20:14:13

标签: .net-core extension-methods fluent-interface

您好,我只希望能够使用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才能在扩展名内访问它,如果可以仅使变量get-able我可以接受从外面。

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

例如:

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

2 个答案:

答案 0 :(得分:2)

听起来您使用的工具错误,扩展方法无法访问非公开成员。

所需的行为仅限于实例方法或属性。我的建议是在类中添加一个实例方法。

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

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. 反射通常比常规实例方法慢得多。 (尽管不经常调用此方法,性能可能并不重要)

答案 1 :(得分:1)

您希望它使用扩展方法来执行此操作,但是在这种情况下您将无法执行。

您最好的选择是

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

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

       return obj;
   }
}