接受其自身字段参数的 C# 接口或抽象 class

C# interface or abstract class that accepts parameter of its own field

我正在尝试创建一个接口或抽象 class,作为许多授权对象的基础。

我的思路是这样的(代码编译不过但我想干活):

public abstract class AuthObject {
  public Enum Values;
  public abstract AuthObject AddPermission(Values permission);
}

一个实现看起来像这样:

public class AuditLogManagement : AuthObject {
  private long _permissions;

  public new enum Values {
    None = 0,
    Read = 1,
    Search = 2,
    Filter = 4,
    Export = 8
  }

  public AuthObject AddPermission(AuditLogManagement.Values permission) {
    _permissions |= (long)permission;
    return this;
  }
}

我的问题的要点是如何将 AddPermission() 的参数限制为接口或抽象中的此对象值字段 (Enum) class。但是我找不到办法。

感谢您的任何想法。

编辑:

一个更简单的用例来解释需求:

interface I {
  AddPermission(I.Values permission);
}

class A : I {
  private long _permissions;

  public enum Values {
    A_a, A_b, A_c
  }
  AddPermission (this.Values newPermission) {
    _permissions |= newPermission;
  }
}

class B : I {
  private long _permissions;

  public enum Values {
    B_a, B_b, B_c
  }
  AddPermission (this.Values newPermission) {
    _permissions |= newPermission;
  }
}

var classA = new A();
var classB = new B();
A.AddPermission(A.Values.A_a); // Allowed
A.AddPermission(B.Values.B_c); // Forbidden! B_c value equals to A_c but is not the same permission!

也许你可以使用泛型?

public abstract class AuthObject<T>
{
    public abstract AuthObject<T> AddPermission(T permission);
}

public class AuditLogManagement : AuthObject<Values>
{
    private Values _permissions;

    public override AuthObject<Values> AddPermission(Values permission)
    {
        _permissions |= permission;
        return this;
    }
}

[Flags]
public enum Values
{
    None = 0,
    Read = 1,
    Search = 2,
    Filter = 4,
    Export = 8
}

你打错了三个字。1


public abstract class AuthObject {
  public Enum Values;
  public abstract AuthObject AddPermission(Values permission);
}

Values这里定义AuditLogManagementclass。每当您想在 AuditLogManagement 之外使用该数据类型时,它都需要是 AuditLogManagement.Values.

这是正确的代码:

public abstract class AuthObject {
  public Enum Values;
  public abstract AuthObject AddPermission(AuditLogManagement.Values permission);
}

你管理的AddPermission方法class没有覆盖抽象基方法。

正确代码:

public override AuthObject AddPermission(AuditLogManagement.Values permission)

(旁注:此处的 AuditLogManagement. 不是必需的)。


你拼错了变量(末尾没有 "s"):

_permissions |= (long)permission;

1:如果有人确实想以打字错误结束问题,请告诉我

您没有正确声明枚举类型。

public enum Values {
    None = 0,
    Read = 1,
    Search = 2,
    Filter = 4,
    Export = 8
}

public abstract class AuthObject {
  public Values Value;
  public abstract AuthObject AddPermission(Values permission);
}

public class AuditLogManagement : AuthObject {
  private long _permissions;
  private Values _values;

  public override AuthObject AddPermission(Values permission) {
    _permissions |= (long)permission;
    return this;
  }
}

我会使用仿制药:

public abstract class AuthObject<T>
     where T : struct, IConvertible // A reasonable way to constrain to an enumeration. 
                                    // you can also use System.Enum for newer versions of C# past 7.3 I believe. 
{
    public T Values { get; } 
    public abstract AuthObject<T> AddPermission(T permission);
}

public enum Values
{
    None = 0,
    Read = 1,
    Search = 2,
    Filter = 4,
    Export = 8
}

public class AuditLogManagement : AuthObject<Values>
{
    private long _permissions;
    public AuthObject AddPermission(Values permission)
    {
        _permissions |= (long)permissions;
        return this;
    }
}

除此之外,我要给出的唯一其他建议是将上面的 'T' 参数命名为更具描述性的名称,例如 'TPermission',因为您不会将它用于典型的容器 class。