использование касательно с классом C#

Эта проблема заняла у меня около одного дня, на одном из моих проектов ASP.NET MVC, к счастью, у меня была проблема на моей машине, а не в производственной среде, поэтому, сравнивая web.config, я вижу и удаляю, что ошибка исчезла ... настоящая проблема - соединить ошибку SQL Server 26 с этой проблемой

18
задан Jeff Yates 9 June 2009 в 16:53
поделиться

6 ответов

Для того, что вы делаете, вам не нужно использовать исх. Если вы передали список с помощью ref, вы позволили бы вызывающей стороне изменить список, на который вы ссылаетесь, вместо того, чтобы просто изменять содержимое списка.

16
ответ дан 30 November 2019 в 05:58
поделиться

This is a common misconception of the use of ref keyword in C#. Its purpose is to pass either a value or a reference type by reference, and you only need it in specific circumstances where you need a direct reference to the actual argument, rather than a copy of the argument (be it a value or reference itself). It is imperative not to confuse reference types with passing by reference in any case.

Jon Skeet has written an excellent article about parameter passing in C#, which compares and contrasts value types, reference types, passing by value, passing by reference (ref), and output parameters (out). I recommend you take some time to read through this in full and your understanding should become much clearer.

To quote the most important parts from that page:

Value parameters:

By default, parameters are value parameters. This means that a new storage location is created for the variable in the function member declaration, and it starts off with the value that you specify in the function member invocation. If you change that value, that doesn't alter any variables involved in the invocation

Reference parameters:

Reference parameters don't pass the values of the variables used in the function member invocation - they use the variables themselves. Rather than creating a new storage location for the variable in the function member declaration, the same storage location is used, so the value of the variable in the function member and the value of the reference parameter will always be the same. Reference parameters need the ref modifier as part of both the declaration and the invocation - that means it's always clear when you're passing something by reference. Let's look at our previous examples, just changing the parameter to be a reference parameter:

To conclude: having read my reply and Jon Skeet's article, I hope that you will then see that there is no need whatsoever for using the ref keyword in the context of your question.

28
ответ дан 30 November 2019 в 05:58
поделиться

Единственный раз, когда вам нужно использовать ref со ссылочным типом, - это если вы собираетесь создать новый объект внутри функции.

Пример №1 : ref ключевое слово не требуется.

// ...
   List myList = new List();
   PopulateList(myList);
// ...
void PopulateList(List AList)
{
   AList.Add("Hello");
   AList.Add("World");
}

Пример №2 : ref ключевое слово необходимо.

// ...
   List myList;
   PopulateList(ref myList);
// ...
void PopulateList(ref List AList)
{
   AList = new List();
   AList.Add("Hello");
   AList.Add("World");
}
11
ответ дан 30 November 2019 в 05:58
поделиться

В двух опубликованных вами фрагментах нет необходимости передавать список по ссылке. По словам Джона Скита, ссылки на объекты передаются по значению. Это означает, что вы захотите указать ссылочный тип, когда метод изменит или может изменить ссылку на объект, и вы хотите, чтобы эта новая ссылка переносилась обратно в вызывающий метод. Например:

void methodA(string test)
{
    test = "Hello World";
}

void methodB(ref string test)
{
    test = "Hello World";
}

void Runner()
{
    string first= "string";
    methodA(first);
    string second= "string";
    methodB(ref second);
    Console.WriteLine((first == second).ToString()); //this would print false
}
2
ответ дан 30 November 2019 в 05:58
поделиться

No you don't need to use ref.

LinkedList is an object, so it is already a reference type. The parameter list is a reference to the LinkedList object.

See this MSDN article for a description of value types. Value types are usually the parameters you would use the ref or out keywords with.

You may also want to pass reference types by ref. This will allow you to point the reference to another object.

Any time you pass an object o you are really passing a reference to the object. When you pass a `ref object o' you are passing a reference to the reference. This allows to you modify the reference.

Passing Reference-Type Parameters may also help you understand.

2
ответ дан 30 November 2019 в 05:58
поделиться

Я добавляю это ответ для программистов, которые, как и я, привыкли к C ++.

Классы, интерфейсы, делегаты и массивы являются ссылочными типами , что означает, что они имеют базовый указатель. Обычные вызовы функций копируют этот указатель (ссылку) по значению, тогда как отправка по ссылке отправляет отправляет ссылку на эту ссылку:

//C# code:
void Foo(ClassA     input)
void Bar(ClassA ref input)

//equivalent C++ code:
void Foo(ClassA*  input)
void Bar(ClassA*& input)

Примитивы, такие как int, double и т. Д., Структуры и строки (строка является исключением из них, но работает аналогично) , размещаются в куче, поэтому все работает немного иначе:

//C# code:
void Foo(StructA     input)
void Bar(StructA ref input)

//equivalent C++ code:
void Foo(StructA  input)
void Bar(StructA& input)

ключевое слово ref необходимо использовать как при объявлении метода, так и при его вызове, чтобы было ясно, что на него есть ссылка:

//C# code:
void Foobar(ClassB ref input)
...
ClassB instance = new ClassB();
Foobar(ref instance);

//equivalent C++ code:
void Foobar(ClassB*& input)
...
ClassB instance* = new ClassB();
Foobar(instance);

Как было сказано ранее, пожалуйста, прочтите это подробное объяснение. Здесь также объясняется, что такое строки.



Интересно отметить, что вызов по ссылке работает с нижележащим указателем, поэтому мы получаем следующий код:

//C# code:
void Foo(ClassA input){
    input = input + 3;
}
void Bar(ClassA ref input){
    input = input + 3;
}
//equivalent C++ code:
void Foo(ClassA&  input){
    input = input + 3;
}
void Bar(ClassA*&  input){
    *input = *input + 3;
}
//equivalent pure C code:
void Fun(ClassA* input){
    *input = *input + 3;
}
void Fun(ClassA** input){
    *(*input) = *(*input) + 3;
}

это грубый эквивалент, но отчасти верный.

2
ответ дан 30 November 2019 в 05:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: