加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

多态问题C#

发布时间:2020-12-15 20:46:12 所属栏目:百科 来源:网络整理
导读:我有一个用户的数据库表,有些是’代理’,有些是’客户’.在我的C#项目中,我有一个User超类和一个Agent和Client子类.代理和客户扩展用户. 在将User对象转换为或更改为Agent或Client对象时,我遇到了一些基本问题.我真的不知道为什么.这可能是相当基本的,但我不
我有一个用户的数据库表,有些是’代理’,有些是’客户’.在我的C#项目中,我有一个User超类和一个Agent和Client子类.代理和客户扩展用户.

在将User对象转换为或更改为Agent或Client对象时,我遇到了一些基本问题.我真的不知道为什么.这可能是相当基本的,但我不知道什么是错的.

public class User
{
    public int UserId { get; set; }
    public string UserType { get; set; }
    public DateTime DateCreated { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
    public string Name { get; set; }
    public string Phone { get; set; }

    public User()
    {
    }
}
public class Agent : User
{
    public string Company { get; set; }
    public string CompanyReg { get; set; }
    public string SecurityQuestion { get; set; }
    public string SecurityAnswer { get; set; }
    public string Description { get; set; }
    public int AccountBalance { get; set; }
    public bool WantsRequests { get; set; }
    public string ImageUrl { get; set; }

    public Agent()
    {
    }
}
public class Client : User
{
    public string Country { get; set; }
    public string IP { get; set; }

    public Client()
    {
    }
}

现在为什么我不能这样做:

public User GetUser(int userid)
    {
        User user = new User();
        User returnuser = user;
        string sql = "SELECT usertype,datecreated,email,name,phone,country,ip,company,companyreg,securityquestion,securityanswer,description,accountbalance,aothcredits,wantsrequests FROM ruser WHERE userid=@userid";
        try
        {
            using (SqlConnection con = new SqlConnection(constr))
            using (SqlCommand cmd = new SqlCommand(sql))
            {
                con.Open();
                cmd.Connection = con;
                cmd.Parameters.Add("@userid",System.Data.SqlDbType.Int).Value = userid;
                using (SqlDataReader rdr = cmd.ExecuteReader())
                {
                    if (rdr.Read())
                    {
                        user.UserId = userid;
                        user.UserType = rdr["usertype"].ToString();
                        user.DateCreated = (DateTime)rdr["datecreated"];
                        user.Email = rdr["email"].ToString();
                        user.Name = rdr["name"].ToString();
                        user.Phone = rdr["phone"].ToString();

                        string type = rdr.GetString(0);
                        if (type == "agent")
                        {
                            Agent agent = user as Agent;
                            agent.Company = rdr["company"].ToString();
                            agent.CompanyReg = rdr["companyreg"].ToString();
                            agent.SecurityQuestion = rdr["securityQuestion"].ToString();
                            agent.SecurityAnswer = rdr["securityanswer"].ToString();
                            agent.Description = rdr["description"].ToString();
                            agent.AccountBalance = (int)rdr["accountbalance"];
                            agent.WantsRequests = Convert.ToBoolean(rdr["wantsrequests"]);
                            returnuser = agent;
                        }
                        else //type == "client"
                        {
                            Client client = user as Client;
                            client.Country = rdr["country"].ToString();
                            client.IP = rdr["ip"].ToString();
                            returnuser = client;
                        }
                    }
                }
            }
        }
        catch (SqlException e)
        {
            throw e;
        }
        return returnuser;
    }

解决方法

如果将对象实例化为基类,则无法从基类强制转换为子类.

您尝试使用as从用户转换为客户端或代理,具体取决于您的数据.但是,您在函数的开头部分创建了一个User对象:

User user = new User();

此对象属于User类型,因此无法将其转换为客户端或代理,并将返回null.请参阅文档here.

The as operator is like a cast except that it yields null on conversion failure instead of raising an exception.

你可以证明如下:

User u = new User();
System.Console.WriteLine("u is User: " + (u is User));
System.Console.WriteLine("u is Agent: " + (u is Agent));
System.Console.WriteLine("u is Client: " + (u is Client));
// Should produce:
// u is User: true
// u is Agent: false
// u is Client: false

Agent a = new Agent();
u = a;
System.Console.WriteLine("u is User: " + (u is User));
System.Console.WriteLine("u is Agent: " + (u is Agent));
System.Console.WriteLine("u is Client: " + (u is Agent));
// Should produce:
// u is User: true
// u is Agent: true
// u is Client: false

您需要做的是显式创建您需要的最具体的类,无论是新代理还是客户端,然后根据需要将其强制转换为更通用的用户.

例如:

public User GetUser(int userid)
    {
        User user;
        string sql = "...";
        try
        {
            using (SqlConnection con = new SqlConnection(constr))
            using (SqlCommand cmd = new SqlCommand(sql))
            {
                //.. Snip sql stuff ... //

                        string type = rdr.GetString(0);
                        if (type == "agent")
                        {
                            Agent agent = new Agent();
                            agent.Company = rdr["company"].ToString();
                            agent.CompanyReg = rdr["companyreg"].ToString();
                            agent.SecurityQuestion = rdr["securityQuestion"].ToString();
                            agent.SecurityAnswer = rdr["securityanswer"].ToString();
                            agent.Description = rdr["description"].ToString();
                            agent.AccountBalance = (int)rdr["accountbalance"];
                            agent.WantsRequests = Convert.ToBoolean(rdr["wantsrequests"]);
                            user = agent;
                        }
                        else //type == "client"
                        {
                            Client client = new Client();
                            client.Country = rdr["country"].ToString();
                            client.IP = rdr["ip"].ToString();
                            user= client;
                        }

                        // Now do generic things
                        user.UserId = userid;
                        user.UserType = rdr["usertype"].ToString();
                        user.DateCreated = (DateTime)rdr["datecreated"];
                        user.Email = rdr["email"].ToString();
                        user.Name = rdr["name"].ToString();
                        user.Phone = rdr["phone"].ToString();

                        return user;
                    }
                }
            }
        }
        catch (SqlException e)
        {
            throw e;
        }
    }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读