具有多种返回类型的索引器

时间:2017-02-20 13:04:32

标签: c#

我在班上使用Indexers来更轻松地搜索列表。但是,我希望能够返回bool和int。不是在同一时间,而是确定它是bool还是int然后返回它。

public class uPermissions
{

    private List<uPermission> permissions = new List<uPermission> ()
    {
        new uPermission ("canBuild", false),
        new uPermission ("canClaim", false),
        new uPermission ("canUnClaim", false),
        new uPermission ("canInvite", false),
        new uPermission ("canKick", false),
        new uPermission ("canSetHome", false)
    };
    private List<uConstraint> constraints = new List<uConstraint> ();

    public bool this[string index]
    {
        get
        {
            return permissions.Where (p => p.name == index).First ().allowed;
        }
        set
        {
            permissions.Where (p => p.name == index).First ().allowed = value;
        }
    }
    public int this[string index]
    {
        get
        {
            return constraints.Where (c => c.name == index).First ().count;
        }
        set
        {
            constraints.Where (c => c.name == index).First ().count = value;
        }
    }

    public bool exists (string permission)
    {
        var perm = permissions.Where (p => p.name.ToLower () == permission.ToLower ()).First ();
        return (perm != null) ? true : false;
    }

    public void setAllTrue ()
    {
        foreach (uPermission p in permissions)
        {
            p.allowed = true;
        }
    }
    public void setAllFalse ()
    {
        foreach (uPermission p in permissions)
        {
            p.allowed = false;
        }
    }
}

public class uConstraint
{
    public string name;
    public int count;

    public uConstraint () { }
    public uConstraint (string name, int count)
    {
        this.name = name;
        this.count = count;
    } 
}

public class uPermission
{
    public string name;
    public bool allowed;

    public uPermission () { }
    public uPermission (string name, bool allowed)
    {
        this.name = name;
        this.allowed = allowed;
    }
}

这是我的代码。我在搜索时看到了一些关于模板的东西,但我不明白它是如何工作的,或者它是否是正确的解决方案。如果有人能提供一些见解,将非常感谢

3 个答案:

答案 0 :(得分:0)

C#中的重载解析机制不考虑返回值。你不能有两个具有相同名称和参数的方法,只有它们的返回类型不同。

Indexer只是一种方法(或两种方法),因此遵循相同的规则。你不能有两个具有相同参数的索引器,只有它们的返回类型不同。

答案 1 :(得分:0)

我建议使用两个不同的属性,每个属性包含一个字典或一些List类型。这样你可以这样写:

bool foo = uPermissionsInstance.Permissions["someName"];
int bar = uPermissionsInstance.Constraints["someOtherName"];

另外,你可以使用“hack”,效果很好:

  • 编写一个实现了两个隐式转换的类。一个用于int,一个用于bool。
  • 返回此类而不是int或bool并适当设置其内部值。

这样你可以写下面的内容。但这不适用于二传手!

bool foo = uPermissionsInstance["someName"];
int bar = uPermissionsInstance["someOtherName"];

实现:

public IntBoolValue this[string index]
{
    get
    {
        // Here you need to check whether you can find an entry in permissions or in constraints. Then return the found value.
        return new IntBoolValue(permissions.Where (p => p.name == index).First ().allowed);
    }
}

// ------------------

internal struct IntBoolValue
{
    internal int internalInt;
    internal bool internalBool;

    public IntBoolValue(int value) { this.internalInt = value; }
    public IntBoolValue(bool value) { this.internalBool = value; }

    public static implicit operator bool(IntBoolValue value)
    {
        return value.internalBool;
    }

    public static implicit operator int(IntBoolValue value)
    {
        return value.internalInt;
    }
}

答案 2 :(得分:0)

C#不允许您根据返回类型区分重载(它们必须至少有一个参数类型或类型参数计数不同)。 您可以创建泛型方法并使用type参数来区分您的两个意图。 E.g。

class uPermissions {
   public T GetAllowedOrCount<T>(string index) {
     get {
       if (typeof(T) == typeof(bool) {
         return permissions.Where (p => p.name == index).First ().allowed;
       } else if (typeof(T) == typeof(int) {
         return constraints.Where (c => c.name == index).First ().count;
       }
       throw new InvalidOperationException("only bool and int are supported");
     }
}

然后您使用显式类型参数调用它,例如

var fooCount = uPermissions.GetAllowedOrCount<int>("foo")
var fooAllowed = uPermissions.GetAllowedOrCount<string>("foo")

请注意,此解决方案不适用于this索引器,因为C#不支持通用索引器。

我想虽然我们同意这听起来不像你想做的事情。您的调度现在是运行时而不是编译时,您肯定不会获得类型安全性

uPermissions.GetAllowedOrCount<double>("foo")

也会编译并爆发运行时异常。

老实说,我也会发现同样(或重载)方法返回/设置两个完全不同的东西(即允许vs计数)非常令人困惑。我宁愿有两种不同的方法,或者从单个方法返回一个数据结构(具有允许/计数的getter)。在后一种情况下,如果你喜欢它,你也可以使用索引器。