向下转C#.NET

Fab*_*ins -1 .net c# downcast

这是我的例子:

public class Person
{
    public string Name { get; set; }
}

public class Client : Person
{
    public string LastName { get; set; }
}

public class Test
{
    Person p = new Person();
    Client c = (Client)p; //throws exception
}
Run Code Online (Sandbox Code Playgroud)

由于客户端继承自Person,为什么我不能这样做呢?如果可以,这是错误的方式,我该怎么办?

OBS:我知道上面的例子会:

Person p = new Client();
Client c = (Client)p;
Run Code Online (Sandbox Code Playgroud)

Ice*_*kle 5

实际上有点绕道而行,你可以进行这样的转换工作,但是,它需要为其他类提供额外的父类,并且需要一个隐式运算符来将客户端转换为Person(尽管这可能不是你原来的那个)

class Program
{
    public abstract class BasePerson
    {
        public string FirstName { get; set; }
    }

    public class Person : BasePerson
    {
    }

    public class Client : BasePerson
    {
        public string LastName { get; set; }

        public static implicit operator Client(Person p)
        {
            if (p == null)
            {
                return null;
            }
            return new Client { FirstName = p.FirstName };
        }
    }

    static void Main(string[] args)
    {
        Person p = new Person { FirstName = "Test" };
        Client c = (Client)p;
        Console.WriteLine(c.FirstName);
        Console.ReadLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

这将编译并提供FirstName到客户端,可能有姓氏,但是,正如我所说,这可能不是你所追求的,只是有可能使你的代码编译,并以最小的变化运行...

UPDATE

正如评论中所讨论的,如果我需要实现这样的转换,我宁愿通过其中任何一个来实现

  • 创建一个帮助方法

    public class Client : Person
    {
        public static Client GetClientFromPerson(Person p) 
        {
            if (p == null) 
            {
                return null;
            }
            return new Client { FirstName = p.FirstName };
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

这将导致:

Client c = Client.GetClientFromPerson(p);
Run Code Online (Sandbox Code Playgroud)
  • 添加第二个构造函数

    public class Client : Person
    {
        public string LastName { get; set; }
    
        public Client()
        {
        }
    
        public Client(Person p) : this()
        {
            FirstName = p.FirstName;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

这将导致:

Client c = new Client(p);
Run Code Online (Sandbox Code Playgroud)

这将使得其他人更容易查看代码,将来可能的维护,并且不需要您更改现有的继承