Поскольку C# - управляемый язык, нет такой вещи, как void*
(что никогда не было действительно хорошей идеей даже в C++). У вас есть два варианта в C#: передать «объект» или использовать генерики. Объект должен быть добавлен к соответствующему типу, который будет использоваться как что-либо, кроме черного ящика. Generics (менее мощная версия шаблонов C#) обычно - путь.
Если вам нужно передать несколько параметров, вы можете использовать C# Tuple
(по аналогии с C void*
массив) или объект массив params
(похожий на C) переменной длины.
В отсутствие хорошего примера того, почему это было бы полезно (если это возможно), это выглядит плохой дизайн.
Я могу видеть из комментариев, что есть много путаницы на эту тему, так что позвольте мне быть абсолютно ясно: class
и struct
в C# и C++ является очень разные. В C++ различие заключается в построении и публичном/частном доступе к полям. В C# различие заключается в том, как они обрабатываются при передаче в качестве параметров.
В C# при объявлении класса и пропуск «класс» (экземпляра класса, на самом деле) в функцию, вы действительно пропускание ссылки к экземпляру класса в функцию. Существует никоим образом, чтобы передать экземпляр класса непосредственно в функцию, как вы можете в C++. В отличие от C++, в C# функция, которую вы вызываете, может изменять данные в экземпляре класса, и такие изменения будут видны вызывающей стороне, потому что на C++ вызывается конструктор копирования и данные экземпляра класса фактически копируются в стек, но в C#, классы ссылки типы.
Вот некоторые примеры, предполагая, что C
является class
и S
является struct
на обоих языках:
В C++:
void func (C c)
{
c.value = true; // This change will NOT be seen by the caller because the class was passed by value
}
void func (C* c)
{
c->value = true; // This change WILL be seen by the caller because the class was passed by reference (pointer in this case, though the distinction is only syntactic)
c = new C(); // This new instance will not be seen by the caller and will never be destroyed or freed
}
void func (C& c)
{
c.value = true; // This change WILL be seen by the caller because the class was passed by reference
}
void func (C** c)
{
(*c)->value = true; // This change will only be seen by the caller if they kept another pointer (reference) to the instance, because the next statement will overwrite the pointer whose pointer was passed into this function
*c = new C(); // A new instance of C WILL be seen by the caller because the pointer to the class was passed by reference (pointer)
}
void func (S s)
{
s.value = true; // This change will NOT be seen by the caller because the struct was passed by value
}
void func (S* s)
{
s->value = true; // This change WILL be seen by the caller because the struct was passed by reference (pointer)
s = new S(); // This new instance will not be seen by the caller and will never be destroyed or freed
}
void func (S& s)
{
s.value = true; // This change WILL be seen by the caller because the struct was passed by reference
}
void func (S** s)
{
(*s)->value = true; // This change will only be seen by the caller if they kept another pointer (reference) to the instance, because the next statement will overwrite the pointer whose pointer was passed into this function
*s = new S(); // A new instance of S WILL be seen by the caller because the pointer to the struct was passed by reference (pointer)
}
И в C#:
void func (C c)
{
c.value = true; // This change will be seen by the caller because the class was passed by reference
}
void func (ref C c)
{
c.value = true; // This change will only be seen by the caller if they kept another reference to the class instance other than the one they passed by reference to this function, because the next statement will overwrite the reference whose reference was passed into this function
c = new C(); // A new instance of C WILL be seen by the caller because the reference to the class was passed (by reference)
}
void func (S s)
{
s.value = true; // This change will NOT be seen by the caller because the struct was passed by value
}
void func (ref S s)
{
s.value = true; // This change will only be seen by the caller if they kept another reference to the struct instance other than the one they passed by reference to this function, because the next statement will overwrite the reference whose reference was passed into this function. I think this would require boxing the original struct instance.
s = new S(); // A new instance of S WILL be seen by the caller because the struct was passed by reference
}
Перейти фактические данные (не ссылки/указатели) по значению в C#, данные должны будет объявлен как struct
.Для получения дополнительной информации см. Microsoft's explanation of structs vs. classes in C#.
Мне совершенно непонятно, что вы просите. Вы показали код на C++ (с некоторым очень сомнительным поведением) - как это связано с вопросом C#? Однако передача классов по ссылке * не * быстрее, чем передача их по значению в C#. –
@ Konrad: Как вы даже передаете класс C# по значению? – James
Как правило, это очень плохая идея для порта 1: 1 при переходе на другой язык. Можете ли вы показать пример C#, чтобы мы могли видеть, что вы на самом деле пытались сделать и не работали должным образом? – walther