Одно различие, как было упомянуто прежде, Вы, не может передать нулевую ссылку, но можно передать нулевого указателя.
Другая вещь, также упомянутая уже, когда Вы звоните f(a,b)
, мог быть беспорядок, если вызывающая сторона не знает, что f
мог потенциально изменить значение для b
Однако еще одна проблема, которая является довольно тонкой, но я все еще столкнулся с ним , семантика ссылок.
Указатели передаются значением, но ссылки не.
, Что означает при передаче параметра указателем можно изменить указатель и заставить его указать на что-то еще.
Рассматривают это:
void f1_ptr( type * a )
{
a = new type(); //no change to passed parameters, you're changing the pointer which was passed by value
}
void f2_ptr( type * a )
{
*a = some_other_value; //now you're changing the value of the parameter that was passed
//or, if type is a class or struct:
a->some_method_that_modifies_object(); //again, changing the parameter that was passed
}
, Но, при передаче ссылкой, Вы не можете изменить ссылку для обращения к другому значению. Как только ссылка установлена, она не может быть изменена.
void f3_ref( type& a )
{
a = type(); //the referred variable has also changed
}
//....
type obj = type( params );
f3_ref( obj ); //obj now changed
f1_ptr( &obj ); //obj doesn't change
f2_ptr( &obj ); //obj now changed
Вы можете посмотреть Сохранение состояния счетчиков , в котором описывается, как создать ленивый список (который кэширует однажды повторяемые элементы).
Я не вижу серьезных проблем с идеей кэширования результатов в списке, как в приведенном выше коде. Наверное, было бы лучше построить список с помощью метода ToList ().
public IEnumerable<ModuleData> ListModules()
{
if (Modules == null)
{
Modules = Source.Descendants("Module")
.Select(m => new ModuleData(m.Element("ModuleID").Value, 1, 1)))
.ToList();
}
return Modules;
}