Переместите нижний отступ от shape
до родительского item
:
-
-
См. http://idunnolol.com/android/drawables.html#layer-list для получения дополнительной информации.
классы BinarySearchTree
и BinarySeachTree
полностью разделены; язык допускает перегрузку универсального типа. Возможно, объявите этот метод для неуниверсального двойного класса:
public static class BinarySearchTree {
public static BinarySearchTree<char> InitializeSampleCharacterBST() {...}
}
public class BinarySearchTree<T> {...} // rest of the code
В противном случае ... какой T
он будет использовать? А что, если статический метод разговаривает со статическими полями? Не говоря уже о том, какой T
использовать, каждый T
получает разные статические поля (то есть SomeType
имеет отдельные поля для SomeType
).
Как сказал Марк, иногда полезно перегрузить тип, чтобы он имел неуниверсальный класс - и это было бы в этом случае.
Что касается того, почему это необходимо, предположим, что статический были фактически реализованы как:
public static BinarySearchTree<char> InitializeSampleCharacterBST()
{
Console.WriteLine(typeof(T));
return null;
}
Это был бы совершенно допустимый код - он в универсальном типе, поэтому он должен иметь доступ к параметру типа ... но вы пытаетесь вызвать метод без предоставления параметра универсального типа, так что это не могло сработать. В вашем случае вы не используете T
где-либо в методе, но это совпадение. Это немного похоже на использование метода экземпляра, который не использует this
: вы не используете экземпляр, но по-прежнему не можете вызывать его, как если бы это был статический метод.
Также как имеющие отдельные статические классы, Еще один полезный прием проектирования - разделение шрифта на неуниверсальные и универсальные части. Таким образом, в тех случаях, когда может быть неудобно определить, какой именно тип у вас есть, вам на самом деле не нужно знать его, чтобы вызвать некоторых членов. Например, иерархия интерфейса коллекции может иметь:
public interface ISomeCollection
{
int Count { get; }
void Clear();
}
public interface ISomeCollection<T> : ISomeCollection
{
void Add(T item);
}
Я сам использовал эту технику для моего порта протокольных буферов на C #, и она оказалась очень полезной (хотя и несколько сложной).
Вы забываете, что параметры типа появляются не только в типе параметра / возвращаемого значения метода. Они также могут появляться в реализации:
public static BinarySearchTree<char> InitializeSampleCharacterBST()
{
var forSomeReason = new T();
Помещая свой метод внутри статического класса с параметром типа, вы говорите, что реализация метода может (сейчас или в какой-либо будущей версии) зависеть от этого параметра типа.
] Если это не так, вы поместили метод не в то место.
Поскольку сам тип является универсальным, вы должны предоставить аргумент типа, даже если интересующий вас статический метод не использует этот аргумент типа. Это просто природа универсальных шаблонов в C # ... они не существуют в необщей форме в любое время. Если бы они это сделали, это вызвало бы конфликты с неуниверсальной версией того же типа.