我有两个类 - Expert和Farmer,它们共享一些共同特征,因此实现了一个抽象类User。用户实现了一个接口IUser。在我的应用程序中,最初填写了常用字段,然后用户指出他们是否是专家/农民。
此时,我想将当前对象转换为专家或农民,以填写单独的唯一字段。我目前的方法是声明IUser user = new Farmer();
然后尝试在适当的时间适当地投射:Farmer farmer = user as Farmer
或Expert expert = user as Expert
。但是,对专家的强制转换总是失败,尽管它们都实现了相同的接口和抽象类。
createUser()
抽象类中定义的函数createFarmer()
或User
,或者只是实例化User
和Farmer
并填充两者中的初始字段,在分时,需要采取任何一个实例,但这些都不是特别优雅。 专家的定义:
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; }
}
谢谢!
答案 0 :(得分:2)
您希望农民如何成为专家?即使 if 它们实现相同的通用接口,它们也完全不同。特别是你的课程有一些不常见的成员:
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
- 类。
另外,您可以在抽象基类中引入一些工厂方法。但是,这样做的缺点是您的基类需要知道所有可能的子类型。因此,引入新的子类会导致更改基类。