2017-02-20 2 views
-1

Я использую Indexers в своем классе, чтобы упростить поиск по списку. Тем не менее, я хочу иметь возможность возвращать как bool, так и int. Не в то же время, но определите, является ли это bool или int, а затем возвращает его.Indexer с несколькими типами возврата

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; 
    } 
} 

Это мой код. Я видел что-то о шаблонах во время поиска, но я не понимаю, как это работает, или если это даже правильное решение. Если кто-то может дать некоторую проницательность, мы будем признательны

+0

возможно, вы должны считать словарь - это было бы быстрее. –

+0

Я бы использовал словарь, но это расширение на другое программное обеспечение, и он использует xml для хранения данных, но синтаксический анализ xml не анализирует словари –

+0

Итак, как бы вы отличались, когда вы должны возвращать bool и когда int? В обоих случаях вы передаете один и тот же аргумент строки. – Evk

ответ

0

Механизм разрешения перегрузки в C# не учитывает возвращаемые значения. У вас не может быть двух методов с тем же именем и аргументом, отличающихся только их возвращаемым типом.

Indexer - это всего лишь метод (или два), поэтому он следует тем же правилам. У вас не может быть двух индексаторов с одинаковыми аргументами, отличающихся только их возвращаемым типом.

0

Я предлагаю использовать два разных свойства, каждый из которых содержит словарь или некоторый тип списка. Таким образом, вы могли бы написать что-то вроде этого:

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

В качестве альтернативы есть «взломать» вы можете использовать, что работает очень хорошо:

  • Написать класс, который имеет два неявных приведений реализованы. Один для 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; 
    } 
} 
0

C# не позволит отличить перегруженные чисто в зависимости от их типов возврата (они должны отличаться по меньшей мере, один тип параметра или тип аргумента счетчика). Вы можете создать общий метод и использовать аргумент типа для различения двух ваших намерений. Например.

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 count). Я бы предпочел иметь два разных метода для этого или вернуть структуру данных (которая имеет getter для allow/count) из одного метода. В последнем случае вы также можете использовать индексаторы, если это то, что вам нравится.

Смежные вопросы