The FormatterServices.GetUninitializedObject is obsolete and shows a warning as shown below if we try to use it in our code. The FormatterServices class is obsolete as per documentation.
What is the alternative for this? Let's find out with an example.
Below is a simple interface.
namespace getuntnitializeobject
{
public interface IMessage
{
string GetEventHubName();
}
}
Using this interface we have two classes defined as below.
namespace getuntnitializeobject
{
internal class NewInvoiceMessage : IMessage
{
private const string EventHubName = "newinvoice";
private readonly bool _someOtherSetting;
public NewInvoiceMessage(bool someOtherSetting)
{
_someOtherSetting = someOtherSetting;
}
public string GetEventHubName()
{
return EventHubName;
}
}
}
namespace getuntnitializeobject
{
internal class NewOrderMessage : IMessage
{
private const string EventHubName = "neworder";
private readonly bool _someOtherSetting;
public NewOrderMessage(bool someOtherSetting)
{
_someOtherSetting = someOtherSetting;
}
public string GetEventHubName()
{
return EventHubName;
}
}
}
To get the event hub name printed via reflection we have use below code in a console app.
using System.Runtime.Serialization;
namespace getuntnitializeobject;
class Program
{
static void Main(string[] args)
{
IReadOnlyList<Type> types = GetAssemblyTypes();
IEnumerable<Type> messagesTypes = types
.Where(t => typeof(IMessage).IsAssignableFrom(t)
&& !t.IsInterface
&& !t.IsAbstract);
foreach (Type t in messagesTypes)
{
Console
.WriteLine($"Type name: {t.FullName} Event hub name: {GetEventHubName(t)}");
}
}
private static string GetEventHubName(Type e)
{
// this is obsolete
IMessage messageInstace =
(IMessage)FormatterServices.GetUninitializedObject(e);
return messageInstace.GetEventHubName();
}
private static IReadOnlyList<Type> GetAssemblyTypes()
{
return AppDomain.CurrentDomain
.GetAssemblies()
.Select(t =>
{
try
{
return t.GetTypes();
}
catch (Exception)
{
return null;
}
})
.Where(t => t != null)
.SelectMany(t => t)
.ToList();
}
}
The code output is as shown below.
We can use RuntimeHelpers.GetUninitializedObject instead of FormatterServices.GetUninitializedObject as shown below to achive the same results.
using System.Runtime.CompilerServices;
//using System.Runtime.Serialization;
namespace getuntnitializeobject;
class Program
{
static void Main(string[] args)
{
IReadOnlyList<Type> types = GetAssemblyTypes();
IEnumerable<Type> messagesTypes = types
.Where(t => typeof(IMessage).IsAssignableFrom(t)
&& !t.IsInterface
&& !t.IsAbstract);
foreach (Type t in messagesTypes)
{
Console
.WriteLine($"Type name: {t.FullName} Event hub name: {GetEventHubName(t)}");
}
}
private static string GetEventHubName(Type e)
{
// this is obsolete
//IMessage messageInstace =
// (IMessage)FormatterServices.GetUninitializedObject(e);
// use below instead
IMessage messageInstace =
(IMessage)RuntimeHelpers.GetUninitializedObject(e);
return messageInstace.GetEventHubName();
}
private static IReadOnlyList<Type> GetAssemblyTypes()
{
return AppDomain.CurrentDomain
.GetAssemblies()
.Select(t =>
{
try
{
return t.GetTypes();
}
catch (Exception)
{
return null;
}
})
.Where(t => t != null)
.SelectMany(t => t)
.ToList();
}
}
No comments:
Post a Comment