簡體   English   中英

通用接口/抽象類的向下轉換失敗

[英]Downcasting failing from common interface/abstract class

我有兩個類-Expert和Farmer,它們都有一些共同的特征,因此實現了一個抽象類User。 用戶實現接口IUser。 在我的應用程序中,最初填寫了通用字段,但隨后用戶指示它們是否是專家/農民。

此時,我想將當前對象投射到“專家”或“農民”中,以填寫各個唯一的字段。 我當前的方法是聲明IUser user = new Farmer(); 然后嘗試在適當的時間進行適當的投放: Farmer farmer = user as FarmerExpert expert = user as Expert 但是,強制轉換為Expert總是失敗,盡管它們都實現了相同的接口和抽象類。

  1. 為什么這個演員失敗了?
  2. 用繼承巧妙地解決此問題的正確方法是什么? 顯然,可以創建在User抽象類中定義的函數createUser()createFarmer() ,或者僅實例化UserFarmer並在兩個字段中都填充初始字段,采用在拆分時間所需的任何實例,但這兩個都不是特別的優雅。

專家的定義:

public partial class Expert : User
    {

        public override Guid Id { get; set; }
        [StringLength(200)]
        public override string Name { get; set; }
        [Key]
        [StringLength(10)]
        public override string phone { get; set; }
        [StringLength(50)]
        public override string state { get; set; }
        [StringLength(50)]
        public override string district { get; set; }
        [StringLength(6)]
        public override string PIN { get; set; }
        public override double geolat { get; set; }
        public override double geolong { get; set; }
        public override int v { get; set; }
        public override int h { get; set; }
        public override string AzureImageURL { get; set; }

        //IParty properties
        public override string ServiceUrl { get; set; }
        public override string ChannelId { get; set; }
        public override string PartyChannelAccountId { get; set; }
        public override string PartyChannelAccountName { get; set; }
        public override string BotChannelAccountId { get; set; }
        public override string BotChannelAccountName { get; set; }
        public override string ConversationAccountId { get; set; }
        public override string ConversationAccountName { get; set; }


        //Expert specific properties
        public double price { get; set; }
        public int totalRating { get; set; }
        public int numberOfRating { get; set; }
        public string description { get; set; }
        public string languages { get; set; }
        double _sortIndex = double.Nan
    }

農民的定義:

public partial class Farmer : User, IVisualizable
    {
        //User override fields
        [Key]
        public override Guid Id { get; set; }
        [StringLength(200)]
        public override string Name { get; set; }
        [StringLength(10)]
        public override string phone { get; set; }
        [StringLength(50)]
        public override string state { get; set; }
        [StringLength(50)]
        public override string district { get; set; }
        [StringLength(6)]
        public override string PIN { get; set; }
        public override double geolat { get; set; }
        public override double geolong { get; set; }
        public override int v { get; set; }
        public override int h { get; set; }
        public override string AzureImageURL { get; set; }

        //IParty properties
        public override string ServiceUrl { get; set; }
        public override string ChannelId { get; set; }
        public override string PartyChannelAccountId { get; set; }
        public override string PartyChannelAccountName { get; set; }
        public override string BotChannelAccountId { get; set; }
        public override string BotChannelAccountName { get; set; }
        public override string ConversationAccountId { get; set; }
        public override string ConversationAccountName { get; set; }

        //Farmer specific properties
        [StringLength(12)]
        public string AadhaarNum { get; set; }
        public int cropId { get; set; }
        [StringLength(1)]
        public string acreage { get; set; }

        /// <summary>
        /// Constructor calling base - sets Guid of farmer
        /// </summary>
        public Farmer() : base()
        {

        }

    }

用戶定義:

public abstract class User : IUser
    {
        public abstract Guid Id { get; set; }
        public abstract string Name { get; set; }
        public abstract string phone { get; set; }
        public abstract string state { get; set; }
        public abstract string district { get; set; }
        public abstract string PIN { get; set; }
        public abstract double geolat { get; set; }
        public abstract double geolong { get; set; }
        public abstract int v { get; set; }
        public abstract int h { get; set; }
        public abstract string AzureImageURL { get; set; }
        public abstract string ServiceUrl { get; set; }
        public abstract string ChannelId { get; set; }
        public abstract string PartyChannelAccountId { get; set; }
        public abstract string PartyChannelAccountName { get; set; }
        public abstract string BotChannelAccountId { get; set; }
        public abstract string BotChannelAccountName { get; set; }
        public abstract string ConversationAccountId { get; set; }
        public abstract string ConversationAccountName { get; set; }

        /// <summary>
        /// Creates a new User with a new Guid already set.
        /// </summary>
        public User()
        {
            Id = Guid.NewGuid();
        }

    }

IUser的定義:

public interface IUser : IParty
    {
        Guid Id { get; set; }
        string Name { get; set; }
        string state { get; set; }
        string district { get; set; }
        string PIN { get; set; }
        double geolat { get; set; }
        double geolong { get; set; }
        int v { get; set; }
        int h { get; set; }
        string AzureImageURL { get; set; }

    }

謝謝!

您如何期望農民成為專家? 即使他們實現了相同的通用接口,它們是完全不同的。 特別是您的班級有一些不常見的成員:

class Expert
{
    public string languages { get; set; }
}
class Farmer
{
    public string AadhaarNum { get; set; }
}

應如何將languages轉換為AadhaarNum 那是不可能的,因此沒有自動投射。 您必須創建一些自己的演員表或轉換,例如

var farmer = new Farmer(expert);

假設兩個類中都有一個復制構造函數:

class Farmer
{
    public Farmer(IUser user)
    {
        this.Name = user.Name;
        ...
        // also set the members that exist only on farmer
    }
}

並針對Expert級。

或者,您可以在抽象基類中引入一些工廠方法。 但是,這樣做的缺點是您的基類需要了解所有可能的子類型。 因此,引入新的子類會導致更改基類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM