I have a class, NetworkClient as a base class :
using System.IO; using System.Net.Sockets; using System.Threading.Tasks; namespace Network { using System; using System.Collections.Generic; using System.Linq; using System.Text; public class NetworkClient { public NetworkClient() { tcpClient = new TcpClient(); } public NetworkClient(TcpClient client) { tcpClient = client; } public virtual bool IsConnected { get; private set; } private StreamWriter writer { get; set; } private StreamReader reader { get; set; } private TcpClient tcpClient { get; set; } public virtual NetworkServerInfo NetworkServerInfo { get; set; } public async virtual void Connect(NetworkServerInfo info) { if (tcpClient == null) { tcpClient=new TcpClient(); } await tcpClient.ConnectAsync(info.Address,info.Port); reader = new StreamReader(tcpClient.GetStream()); writer = new StreamWriter(tcpClient.GetStream()); } public virtual void Disconnect() { tcpClient.Close(); reader.Dispose(); writer.Dispose(); } public async virtual void Send(string data) { await writer.WriteLineAsync(data); } public async virtual Task<string> Receive() { return await reader.ReadLineAsync(); } } }
And also have a child class derived from NetworkClient :
using System.Net; namespace Network { using Data; using System; using System.Collections.Generic; using System.Linq; using System.Text; public class SkyfilterClient : NetworkClient { public virtual IPAddress Address { get; set; } public virtual int Port { get; set; } public virtual string SessionID { get; set; } public virtual User UserData { get; set; } protected virtual bool Authenticate(string username, string password) { throw new System.NotImplementedException(); } } }
The problem is, that when im trying to cast NetworkClient into SkyfilterClient. An exception is thrown, Unable to cast object of type 'Network.NetworkClient' to type 'Network.SkyfilterClient'.
Whats wrong with my code ? I see that Stream can be converted to NetworkStream, MemoryStream. Why NetworkClient can't be converted to Skyfilter Client?
C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr. Stroustroupe.
C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.
C is more difficult to learn than JavaScript, but it's a valuable skill to have because most programming languages are actually implemented in C. This is because C is a “machine-level” language. So learning it will teach you how a computer works and will actually make learning new languages in the future easier.
As long as the object is actually a SkyfilterClient
, then a cast should work. Here is a contrived example to prove this:
using System; class Program { static void Main() { NetworkClient net = new SkyfilterClient(); var sky = (SkyfilterClient)net; } } public class NetworkClient{} public class SkyfilterClient : NetworkClient{}
However, if it is actually a NetworkClient
, then you cannot magically make it become the subclass. Here is an example of that:
using System; class Program { static void Main() { NetworkClient net = new NetworkClient(); var sky = (SkyfilterClient)net; } } public class NetworkClient{} public class SkyfilterClient : NetworkClient{}
HOWEVER, you could create a converter class. Here is an example of that, also:
using System; class Program { static void Main() { NetworkClient net = new NetworkClient(); var sky = SkyFilterClient.CopyToSkyfilterClient(net); } } public class NetworkClient { public int SomeVal {get;set;} } public class SkyfilterClient : NetworkClient { public int NewSomeVal {get;set;} public static SkyfilterClient CopyToSkyfilterClient(NetworkClient networkClient) { return new SkyfilterClient{NewSomeVal = networkClient.SomeVal}; } }
But, keep in mind that there is a reason you cannot convert this way. You may be missing key information that the subclass needs.
Finally, if you just want to see if the attempted cast will work, then you can use is
:
if(client is SkyfilterClient) cast
I'm surprised AutoMapper hasn't come up as an answer.
As is clear from all the previous answers, you cannot do the typecast. However, using AutoMapper, in a few lines of code you can have a new SkyfilterClient
instantiated based on an existing NetworkClient
.
In essence, you would put the following where you are currently doing your typecasting:
using AutoMapper; ... // somewhere, your network client was declared var existingNetworkClient = new NetworkClient(); ... // now we want to type-cast, but we can't, so we instantiate using AutoMapper AutoMapper.Mapper.CreateMap<NetworkClient, SkyfilterClient>(); var skyfilterObject = AutoMapper.Mapper.Map<SkyfilterClient>(existingNetworkClient);
Here's a full-blown example:
public class Vehicle { public int NumWheels { get; set; } public bool HasMotor { get; set; } } public class Car: Vehicle { public string Color { get; set; } public string SteeringColumnStyle { get; set; } } public class CarMaker { // I am given vehicles that I want to turn into cars... public List<Car> Convert(List<Vehicle> vehicles) { var cars = new List<Car>(); AutoMapper.Mapper.CreateMap<Vehicle, Car>(); // Declare that we want some automagic to happen foreach (var vehicle in vehicles) { var car = AutoMapper.Mapper.Map<Car>(vehicle); // At this point, the car-specific properties (Color and SteeringColumnStyle) are null, because there are no properties in the Vehicle object to map from. // However, car's NumWheels and HasMotor properties which exist due to inheritance, are populated by AutoMapper. cars.Add(car); } return cars; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With