Редактировать: Макеты из этого ответа теперь устарели. Используйте решение, предложенное Евгением Брюсовым . Также, спасибо chancyWu за комментарий.
Теперь появился лучший способ с поддержкой библиотеки версии 23.0.0 (о времени, верно?). Теперь вы можете использовать PercentFrameLayout или PercentRelativeLayout .
Если бы вы хотели, чтобы EditText составлял 80% ширины экрана с полем 10% по обе стороны, код был бы похож на это:
Вы также можете взглянуть на PercentLayoutHelper.PercentLayoutParams
Хотя в данном конкретном сценарии это может быть очевидным, существует множество сценариев, в которых на самом деле это неочевидно. Возьмем для примера следующий API
class Bar {
public static int Foo();
public static string Foo();
}
. Для компилятора просто невозможно узнать, какой Foo вызывать в следующих сценариях
void Ambiguous() {
Bar.Foo();
object o = Bar.Foo();
Dog d = (Dog)(Bar.Foo());
var x = Bar.Foo();
Console.WriteLine(Bar.Foo());
}
Это всего лишь несколько быстрых примеров. Несомненно, существуют более надуманные и злые проблемы.
Из последнего абзаца раздела 1.6.6 спецификации языка C # 3.0 :
Сигнатура метода должна быть уникальной в классе, в котором этот метод объявляется. Сигнатура метода состоит из имени метода, количества параметров типа и числа, модификаторов и типов его параметров. Сигнатура метода не включает тип возвращаемого значения.
В IL два метода могут отличаться только типом возвращаемого значения, но вне отражения нет средств для вызова метода, который отличается только типом возвращаемого значения.
Задумывались ли вы об использовании универсальных шаблонов для возврата правильного типа.
public T SomeFunction<T>()
{
return T
}
int x = SomeFunction<int>();
string y = SomeFunction<string>();
Примечание. Этот код не тестировался
Функции, отличающиеся только возвращаемыми значениями, не подлежат перегрузке.
int x = FunctionReturnsIntOrString();
double y = FunctionReturnsIntOrString();
В приведенном выше случае компилятор может идентифицировать правильные функции, но рассматривать случаи, в которых возвращаемые значения не указаны, это неоднозначно.
FunctionReturnsIntOrString(); //int version
FunctionReturnsIntOrString(); //double version
Компилятор не может разрешить здесь перегруженные методы.
Я думаю, вы хотите серьезно пересмотреть то, что вы делаете и как, но вы МОЖЕТЕ сделать это:
int i = FunctionReturnsIntOrString<int>();
string j = FunctionReturnsIntOrString<string>();
, реализовав это следующим образом:
private T FunctionReturnsIntOrString<T>()
{
int val = 1;
if (typeof(T) == typeof(string) || typeof(T) == typeof(int))
{
return (T)(object)val;
}
else
{
throw new ArgumentException("or some other exception type");
}
}
но есть ооочень много причин не делать этого.
Тип возвращаемого значения не является частью сигнатуры метода, только имя и типы параметров. Из-за этого у вас не может быть двух методов, которые отличаются только типом возвращаемого значения. Один из способов обойти это - чтобы ваш метод возвращал объект, а затем вызывающий код должен привести его либо к типу int, либо к строке.
Однако может быть лучше создать два разных метода или создать класс для возврат из метода, который может содержать либо int, либо строку.
Потому что иногда он действительно не может сказать, какой из них следует использовать (в вашем примере он мог бы, но не все случаи так однозначны):
void SomeMethod(int x) { ... }
void SomeMethod(string x) { ... }
В этом контексте, если вы вызываете SomeMethod (FunctionReturnsIntOrString ())
, что должен делать компилятор?
В C # нет типов, возвращаемых overridin, IL поддерживает такой вид переопределения, но C # еще не ...
Вам также не требуется присваивать значение вызываемому методу. Например:
int FunctionReturnsIntOrString() {return 0;}
string FunctionReturnsIntOrString() {return "some string";}
//some code
//...
int integer = FunctionReturnsIntOrString(); //It probably could have figured this one out
FunctionReturnsIntOrString(); //this is valid, which method would it call?