Свойство или индексатор не могут передаваться в качестве параметра out или ref
Я получаю вышеуказанную ошибку и не могу ее разрешить. Я немного погуглил, но не могу избавиться от него.
сценарий:
у меня есть класс BudgetAllocate, свойство которого-бюджет, который имеет двойной тип.
в моем dataAccessLayer,
в одном из моих классов я пытаюсь сделать это:
double.TryParse(objReader[i].ToString(), out bd.Budget);
который бросает эту ошибку:
свойство или индексатор не могут быть переданы в качестве параметра out или ref на компилировать время.
Я даже попытался это:
double.TryParse(objReader[i].ToString().Equals(DBNull.Value) ? "" : objReader[i].ToString(), out bd.Budget);
все остальное работает нормально и ссылки между слоями присутствуют.
6 ответов
вы не можете использовать
double.TryParse(objReader[i].ToString(), out bd.Budget);
заменить bd.Бюджет с некоторой переменной.
double k;
double.TryParse(objReader[i].ToString(), out k);
другие дали вам решение, но почему это необходимо: свойство-это просто синтаксический сахар для метод.
например, при объявлении свойства с именем Name
с геттером и сеттером под капотом компилятор фактически генерирует методы, называемые get_Name()
и set_Name(value)
. Затем при чтении и записи в это свойство компилятор преобразует эти операции в вызовы этих созданных методов.
когда вы считаете это становится очевидным, почему вы не можете передать свойство в качестве выходного параметра - вы фактически передадите ссылку на метод, а не Ссылка на объект a переменная, что и ожидает выходной параметр.
аналогичный случай существует для индексаторов.
Это случай протекающей абстракции. Свойство на самом деле является методом get и set аксессоры для индексатора компилируются в методы get_Index() и set_Index. Компилятор делает потрясающую работу, скрывая этот факт, он автоматически переводит назначение свойству в соответствующий метод set_Xxx (), например.
но это идет брюхом вверх, когда вы передаете параметр метода по ссылке. Это требует, чтобы компилятор JIT передал указатель на расположение в памяти переданного аргумента. Проблема в том,что нет ни одного, присвоение значения свойства требует вызова метода setter. Вызываемый метод не может определить разницу между переданной переменной и переданным свойством и поэтому не может знать, требуется ли вызов метода.
Примечательно, что это действительно работает в VB.NET - ... Например:
Class Example
Public Property Prop As Integer
Public Sub Test(ByRef arg As Integer)
arg = 42
End Sub
Public Sub Run()
Test(Prop) '' No problem
End Sub
End Class
VB.NET компилятор решает это, автоматически генерируя этот код для запуска метод, выраженный в C#:
int temp = Prop;
Test(ref temp);
Prop = temp;
это решение можно использовать также. Не совсем уверен, почему команда c# не использовала тот же подход. Возможно, потому, что они не хотели скрывать потенциально дорогие звонки геттера и сеттера. Или полностью недиагностируемое поведение, которое вы получите, когда сеттер имеет побочные эффекты, изменяющие значение свойства, они исчезнут после назначения. Классическая разница между C# и VB.NET, C# - "никаких сюрпризов", VB.NET это " сделать это работайте, если можете".
поместите параметр out в локальную переменную, а затем установите переменную в bd.Budget
:
double tempVar = 0.0;
if (double.TryParse(objReader[i].ToString(), out tempVar))
{
bd.Budget = tempVar;
}
обновление: прямо из MSDN:
свойства не являются переменными и поэтому не может быть принят как параметры.
http://msdn.microsoft.com/en-us/library/t3c3bfhx (v=против 80).aspx
возможно, интерес - вы могли бы написать свой собственный:
//double.TryParse(, out bd.Budget);
bool result = TryParse(s, value => bd.Budget = value);
}
public bool TryParse(string s, Action<double> setValue)
{
double value;
var result = double.TryParse(s, out value);
if (result) setValue(value);
return result;
}
Итак, бюджет-это свойство, правильно?
Сначала установите его в локальную переменную, а затем установите значение свойства.
double t = 0;
double.TryParse(objReader[i].ToString(), out t);
bd.Budget = t;