Добрый день!
Подскажите пожалуйста есть ли какие-либо варианты реализации. Нужно реализовать следующую логику (ниже). В моем случае компилятор выдает ошибку, что и понятно.
Но непонятно как сделать так, чтоб эта логика работала. Важный момент, в моем случае я не могу переделать МyStruct1 на класс, это должна быть именно структура.
public interface IMessage
{
int GetMessageType();
}
struct MyStruct1 : IMessage
{
public int GetMessageType()
{
return 1;
}
}
struct MyStruct2 : IMessage
{
public int GetMessageType()
{
return 2;
}
}
public interface IObject
{
void OnReceive<T>(ref T message_) where T : IMessage;
}
class TestClass : IObject
{
public void OnReceive<T>(ref T message_) where T : IMessage
{
int type = message_.GetMessageType();
switch (type)
{
case 1: OnReceiveMessage(ref message_); break; // error CS1502: The best overloaded method match for 'Test.TestClass.OnReceiveMessage(ref Test.MyStruct1)' has some invalid arguments
}
}
public void OnReceiveMessage(ref MyStruct1 message_)
{
}
}
Ничего лучше этого не смог придумать (ниже), но тут на каждую структуру по выделению памяти происходит. Если кто что придумает пишите.
public class XMessage<T> where T : IMessage
{
public T m_Message;
};
public interface IObject
{
void OnReceive<T>(XMessage<T> message_) where T : IMessage;
}
class TestClass : IObject
{
public void OnReceive<T>(XMessage<T> message_) where T : IMessage
{
int type = message_.m_Message.GetMessageType();
if (type == 1)
OnReceiveMessage(message_ as XMessage<MyStruct1>);
}
public bool OnReceiveMessage(XMessage<MyStruct1> message_)
{
return true;
}
}
Здравствуйте, xorix, Вы писали:
X>Добрый день! X>Подскажите пожалуйста есть ли какие-либо варианты реализации. Нужно реализовать следующую логику (ниже). В моем случае компилятор выдает ошибку, что и понятно. X>Но непонятно как сделать так, чтоб эта логика работала. Важный момент, в моем случае я не могу переделать МyStruct1 на класс, это должна быть именно структура.
1. Изучаем, как работают генерики
il-код верифицируется на этапе компиляции, разрешение перегрузок происходит тогда же. Реальные типы подставляются позже, в рантайме.
Компилятор не может гарантировать, что тип T будет всегда MyStruct1 и посылает код лесом.
2. Использование ref-параметров без явной и очевидной причины является плохой практикой и приводит к очень неприятным сюрпризам. Особенно если передаётся базовый тип. В частности, поэтому компилятор не позволяет трюки вида
public void DoDarkMagic(ref Control control)
{
control = new TextBox();
}
public void Main()
{
Button button = new Button();
DoDarkMagic(ref button);
// Now your button magically became a text box ...
}
3. Начните проектировать APT от сценариев использования. Очень помогает от ситуаций "ух что придумал! Менять всё поздно, но как это теперь использовать?"
Здравствуйте, xorix, Вы писали:
X>Ничего лучше этого не смог придумать (ниже), но тут на каждую структуру по выделению памяти происходит. Если кто что придумает пишите.
1. Читаем Рихтера По выделению памяти тут не происходит.
2. Вам здесь вообще T не нужно. Заведите базовый класс без генерик-параметра и кастьте его к нужному вам типу.
или используйте
dynamic x = message;
OnReceiveMessage(x); // разрешение перегрузок будет происходить в рантайме
>> 1. Читаем Рихтера По выделению памяти тут не происходит.
Происходит, я просто не написал код где это происходит. У меня приезжает структура и соответственно если бы я дальше передавал структуру
то все было бы на стеке. А так обарачивая структуру в мембер класса, клас создается в хипе, соответственно на каждую приезжающую структуру
выделяется память под калсс и структуру.
>>dynamic x = message;
Про dynamic спасибо, попробую. А не подскажите dynamic своим поздним связыванием не будет аффектить перфоманс?
Здравствуйте, xorix, Вы писали:
X>А так обарачивая структуру в мембер класса, клас создается в хипе, соответственно на каждую приезжающую структуру X>выделяется память под калсс и структуру.
Не совсем так, отдельная память под структуру не выделяется, в самом экземпляре класса хранится.
>>>dynamic x = message; X>Про dynamic спасибо, попробую. А не подскажите dynamic своим поздним связыванием не будет аффектить перфоманс?
Нет. В своё время проверял — сопоставимо с поиском в словаре и вызовом делегата. Но ничего не мешает перепроверить самому
X>>А так обарачивая структуру в мембер класса, клас создается в хипе, соответственно на каждую приезжающую структуру X>>выделяется память под калсс и структуру. S>Не совсем так, отдельная память под структуру не выделяется, в самом экземпляре класса хранится.
Да, все верно вы говорите, но я имел ввиду немного другое, что память будет выделяться под класс, т.е.:
вместо того чтоб просто дальше передать структуру: