这是一个简单的概念,我之前没有遇到任何麻烦,所以非常感谢帮助。
public partial class Player
{
public string Name
{ get; private set; }
public int Id
{ get; private set; }
}
public partial class ExtendedPlayer : Player
{
public string Color = "";
}
public class MainProgram
{
static void Main()
{
Player p = new Player();
// The following creates a null object "ep":
ExtendedPlayer ep = p as ExtendedPlayer;
// For proof, NullReferenceException is thrown here:
ep.Color = "red";
}
}
我在SO上阅读的其他一些文章依次创建ep
,然后手动为其分配p
的所有值。这是不可能的,因为Player
只是可读的。
我读过的另一个解决方案是将Player
变为interface
,但由于存在Player对象,我无法做到这一点。
P.S。在我的情况下,Player
实际上是图书馆的一部分。我创建了库,因此我可以更改其属性,但我不希望属性可编辑。但是,如果这会产生问题,我可以改变它是偏的事实。
答案 0 :(得分:3)
您可以创建一个Player
的受保护构造函数来初始化值:
public class Player {
// other stuff same as in your example...
protected Player(string name, int id) {
this.Name = name;
this.Id = id;
}
}
public class ExtendedPlayer : Player {
public ExtendedPlayer(Player p) : base(p.Name, p.Id) { }
}
// in your Main method, you can create an ExtendedPlayer from a Player like so:
Player p = new Player();
ExtendedPlayer e = new ExtendedPlayer(p);
一件事:as
运算符不会将对象从一种类型转换为另一种类型。相反,它试图将一个变量的值转换为不同的类型。类型必须兼容。您不能将任何类型转换为任何其他类型。您可以在此处和其他地方阅读有关投射的信息:http://msdn.microsoft.com/en-us/library/ms173105.aspx。
另一件事:您需要某种方式来初始化Player
类中的字段。就像现在一样,值将是默认值(字符串为null,int为0)。也许你有更多我们没有看到的代码,所以这可能不是问题。但是,请注意,初始化播放器的机制与派生类如何初始化属于基类Player
的字段相关(如上面的代码所示)。
您需要问自己的问题是您希望将Player
转换为ExtendedPlayer
的原因。为什么不首先创建ExtendedPlayer
?我认为你的模型可能没有经过深思熟虑,所以花点时间考虑一下你将Player
转换成ExtendedPlayer
时你真正要做的事情,也许这个问题就会消失。 / p>
答案 1 :(得分:1)
如果要动态地向类中添加功能/行为,则应该查看装饰器模式。 ExtendedPlayer的实现将是这样的:
public interface IPlayer
{
string Name {get;}
string Id {get;}
}
public class Player: IPlayer
{
public string Id {get; private set;}
public string Name {get; private set;}
Player (string name, string id)
{
Name = name;
Id = id;
}
}
public class ExtendedPlayer: IPlayer
{
private IPlayer _player;
public string Id {get { return _player.Id; }}
public string Name {get { return _player.Name + ", " + Color; }}
public string Color{ {get;set;}
Player (IPlayer player, string color)
{
_player = player;
Color = color;
}
}
IPlayer player = new Player("12", "Video player");
player = new ExtendedPlayer(player, "red");
Console.WriteLine(player.Id); // prints 12
Console.WriteLine(player.Name); // prints Video player, red
Console.WriteLine(((ExtendedPlayer)player).Color); // prints red
答案 2 :(得分:0)
您无法从播放器升级到ExtendedPlayer。看起来你正在使用c# - 所以看看扩展方法。 http://msdn.microsoft.com/en-us/library/bb383977.aspx
我并不完全清楚你为什么不在main中创建一个ExtendedPlayer而不是Player类型。 ExtendedPlayer派生自Player,因此您无法将Player转换为ExtendedPlayer,但您可以将ExtendedPlayer转换为Player。