2016-06-07 2 views
-4

UPDATE: Я понимаю, основные понятия C#, я должен объяснять это плохо ...В чем разница между методом расширения и методом с параметром ref?

поток = Тип ссылки, указатель на ячейку памяти, которая содержит реальный объект

Параметр = Passed как тип объекта (поток по-прежнему является Ссылочный тип, а INT будет тип значения)

Ссылка Параметр = Позволяет манипуляции параметра, который будет сохраняться за пределами метода.

Чтобы посмотреть на это еще несколько и выполнить некоторые тесты, кажется, что ответ зависит от того, что я пытаюсь сделать. Этот вопрос помог мне отличить то, что я пытался сделать для своих тестов: How can I get an extension method to change the original object?

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


Созерцая некоторые из вспомогательных классов я создал, мне было интересно, если есть какие-либо функциональные или эксплутационные различия между расширениями и методами с параметром исх. В частности, с чем-то большим, чем потоки, первым я сказал, что передача потока по ref будет более результативной при выполнении различных проверок в указанном потоке, но методы расширения также имеют ссылку, такую ​​как подпись, в том, что они являются статическими.

static bool IsValidSize(this Stream stream, long size) 

bool IsValidSize(ref Stream stream, long size) 

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

+0

Но вы не должны пропускать пар к методу расширения пара. Я думаю, вам нужно посетить документацию по каждому. – Paparazzi

+2

Этот вопрос не имеет никакого смысла; Я думаю, вы не понимаете, что такое параметр ref. –

+0

«Ref Parameter = Позволяет манипулировать параметром, который будет сохраняться вне блока методов» - на самом деле это то, что вы можете сделать с любым объектом ссылочного типа ** с ключевым словом 'ref' ** или без него. Ваше описание - это функциональность, которую вы получаете, если параметр является типом значения. Если это ссылочный тип, это будет ссылка на ссылку объекта, который является более тонким, чем ваш вопрос. –

ответ

4

В этом примере:

bool IsValidSize(ref Stream stream, long size) 

Вы не прошли бы stream по ref, если вы не предназначены для IsValidSize для изменения потока, используемого абонентом.

Что касается методов расширения, то их преимущество заключается в том, что вы не используете множество «вспомогательных» классов, которые вы должны использовать. Вместо этого методы, как представляется, являются частью класса, который они распространяют. Таким образом, вы можете сказать:

stream.IsValidSize(size); 

вместо:

StreamHelper.IsValidSize(stream, size); 

Когда вы говорите, что:

прохождения потока по реф будет более производительным

I подумайте, что вы не совсем понимаете разницу между значениями и ссылочными типами в C#. stream - ссылочный тип, поэтому, когда он передается другой функции, копия, если она не сделана из потока.Вместо этого вызывающий и вызывающий обе указывают (т.е. ссылку) тот же самый экземпляр stream. Это означает, что прохождение вокруг ссылочных типов очень быстрое и легкое. Типы значений различаются, поскольку копия создается всякий раз, когда они назначаются или передаются в функции.

+0

Хорошо, для этого примера передача по ref глупа, но позволяет сказать, что метод был назван «TrimEndBytes», передал бы поток по ref более эффективно, чем расширение, которое делало это? Я понимаю, что ссылочные типы передаются по значению, которое является только значением местоположения объекта (https://msdn.microsoft.com/en-us/library/s6938f28.aspx). Функционально, по-видимому, нет никакой разницы между этими двумя сигнатурами, я просто хотел узнать, знает ли кто-нибудь о различии, поскольку оба они делают то же самое с различными реализациями. – Dan

+2

Я не думаю, что вы понимаете, что передача по ref не относится к типу ссылки или типу значения. См. Документацию https://msdn.microsoft.com/en-us/library/14akc2c7.aspx – Paparazzi

0

Метод расширения позволяет вам добавить метод к классу, который уже существует, без необходимости доступа к исходному коду.

Передача методом ссылки и расширения не относится.

0

В чем разница между методом расширения и методом с параметром ref?

В том, как вы ее называете, разница как этот

public static void ConcatExtension(this string s, string strToAppend) { 
    s = s + strToAppend; 
} 
// ... sometime later 
string str = "this is "; 
str.ConcatExtension("my string"); 

, которая отличается от статического метода с параметром реф

public static void ConcatStatic(ref string s, string strToAppend) { 
    s = s + strToAppend; 
} 
// ... sometime later 
string str = "this is "; 
ConcatStatic(str, "my string"); 

С точки зрения функциональности, это то же самое в этом примере. Однако с параметром ref вы можете изменить то, что он ссылается, тогда как с помощью метода расширения вы не можете изменить то, что указывает параметр this.

Возьмите этот пример.

public static void StringBecomesFoo(ref string s) { 
    s = "Foo"; 
} 

// ... 
var myStr = "something"; 
Console.WriteLine(myStr); // outputs "something" 
StringBecomesFoo(ref myStr); 
Console.WriteLine(myStr); // outputs "Foo" 

Это не возможно просто путем замены ref с this. Так что это еще одно различие.

Смежные вопросы