обсуждение
Как указывают некоторые ответы, .Net строго обеспечивает безопасность типов в рамках вопроса. reinterpret_cast
по своей сути является небезопасной операцией, поэтому возможные способы ее реализации — либо через рефлексию, либо через сериализацию, тогда как оба они связаны.
Как вы упомянули в обновлении, возможное использование может быть инфраструктурой RPC. Библиотеки RPC в любом случае обычно используют сериализацию/рефлексию, и есть несколько пригодных для использования:
так что, возможно, вы не захотите писать его сами.
Если ваш класс Base
будет использовать общедоступные свойства, вы можете использовать AutoMapper:
class Base
{
public int Counter { get; set; }
// ...
}
...
AutoMapper.Mapper.CreateMap<Base, Foo>();
Foo foo = AutoMapper.Mapper.Map<Foo>(b);
Где Foo
вообще не обязательно должно быть получено из Base
. Он просто должен иметь свойство, которое вы хотите отобразить. Но опять же, вам может вообще не понадобиться два типа — решением может стать переосмысление архитектуры.
Как правило, нет необходимости использовать reinterpret_cast
благодаря чистой архитектуре, которая хорошо вписывается в шаблоны, используемые в .Net Framework. Если вы все еще настаиваете на том, чтобы иметь что-то подобное, вот решение с использованием компактной библиотеки сериализации protobuf-net< /а>.
решение для сериализации
Ваши занятия:
using System;
using System.IO;
using ProtoBuf;
using ProtoBuf.Meta;
[ProtoContract]
[ProtoInclude(3, typeof(Foo))]
class Base
{
[ProtoMember(1)]
protected int counter = 0;
public Base(int c) { counter = c; }
public Base() { }
}
[ProtoContract]
class Foo : Base
{
public int Counter { get { return counter; } }
}
и работающий пример сериализации-десериализации:
class Program
{
static void Main(string[] args)
{
Base b = new Base(33);
using (MemoryStream stream = new MemoryStream())
{
Serializer.Serialize<Base>(stream, b);
Console.WriteLine("Length: {0}", stream.Length);
stream.Seek(0, SeekOrigin.Begin);
Foo f=new Foo();
RuntimeTypeModel.Default.Deserialize(stream, f, typeof(Foo));
Console.WriteLine("Foo: {0}", f.Counter);
}
}
}
вывод
Length: 2
Foo: 33
Если вы не хотите объявлять производные типы в своем контракте, см. этот пример...
Как видите, сериализация чрезвычайно компактна.
Если вы хотите использовать больше полей, вы можете попробовать неявную сериализацию полей:
[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
Общий reinterpret_cast
, безусловно, можно реализовать либо с помощью этого решения для сериализации, либо напрямую с помощью отражения, но в данный момент я бы не стал тратить время.
person
Dmitry Ledentsov
schedule
22.10.2013
C#
более типобезопасен, чемC++
. - person Hamlet Hakobyan   schedule 21.10.2013reinterpret_cast
, по своей природе небезопасен, так как вы вряд ли сможете сказать, правильно ли он работал. Используя сериализацию (бинарную, если вам нужна компактная), вы получаете более тонкий контроль над файлами, в частности, над частичным отказом. Как замечают другие комментаторы, система типов .Net должна быть безопасной :) - person Dmitry Ledentsov   schedule 22.10.2013