c# - 访问列表通过指定派生类
问题描述
我有一个抽象的 Player 类,其中包含派生的 HockeyPlayer、BasketballPlayer 和 BaseballPlayer。
public abstract class Player
{
enum PlayerType
{
HockeyPlayer,
BasketballPlayer,
BaseballPlayer
}
public abstract void Points();
private int playerId;
private string playerName;
private string teamName;
private int gamesPlayed;
public int PlayerId
{
get { return playerId; }
set { playerId = value; }
}
public string PlayerName
{
get { return playerName; }
set { playerName = value; }
}
public string TeamName
{
get { return teamName; }
set { teamName = value; }
}
public int GamesPlayed
{
get { return gamesPlayed; }
set { gamesPlayed = value; }
}
}
public class HockeyPlayer : Player
{
private int assists;
private int goals;
public override void Points()
{
int totalPoints = assists + (2 * goals);
}
public int Assists
{
get { return assists; }
set { assists = value; }
}
public int Goals
{
get { return goals; }
set { goals = value; }
}
}
public class BasketballPlayer : Player
{
private int fieldGoals;
private int threePointers;
public override void Points()
{
int totalPoints = (fieldGoals - threePointers) + (2 * threePointers);
}
public int FieldGoals
{
get { return fieldGoals; }
set { fieldGoals = value; }
}
public int ThreePointer
{
get { return threePointers; }
set { threePointers = value; }
}
}
public class BaseballPlayer : Player
{
private int runs;
private int homeRuns;
public override void Points()
{
int totalPoints = (runs - homeRuns) + (2 * homeRuns);
}
public int Runs
{
get { return runs; }
set { runs = value; }
}
public int HomeRuns
{
get { return homeRuns; }
set { homeRuns = value; }
}
}
}
接下来在我的控制器中,我创建了一个列表并添加了一些 HockeyPlayers、BasketbalPlayers、BaseballPlayers
class Controller
{
private static List<Player> players = new List<Player>();
static void Main(string[] args)
{
players.Add(new HockeyPlayer() { PlayerId = 1, PlayerName = "Mitch marner", TeamName = "Toronto Maple Leafs", GamesPlayed = 5, Assists = 12, Goals = 7 });
players.Add(new BasketballPlayer() { PlayerId = 2, PlayerName = "Kyle Lowry", TeamName = "Toronto Raptors", GamesPlayed = 15, FieldGoals = 12, ThreePointer = 7 });
players.Add(new BaseballPlayer() { PlayerId = 3, PlayerName = "Jose Bautista", TeamName = "Toronto Blue Jays", GamesPlayed = 5, Runs = 12, HomeRuns = 7 });
稍后在控制器类中,我有一个仅用于显示 hockeyPlayers 的方法,因此 enum playerType == Player.HockeyPlayer
static void viewHockeyPlayer()
{
Console.WriteLine("View ALL hockey players");
Console.WriteLine($"{"Player Id",-15} {"Player Name",-15} { "Team Name",-15} {"Games Played",5} {"Assists",5} {"Goals",5}\n");
foreach (var hock in players)
{
Console.WriteLine($"{hock.PlayerId,-15} {hock.PlayerName,-15} { hock.TeamName,-15} { hock.GamesPlayed, 5}");
}
}
如您所见,我无法添加仅针对 HockeyPlayer 类的 {hock.Assists} 或 {hock.Goals}。同样到目前为止,我这个方法打印出所有的 PlayerTypes,我无法弄清楚如何只打印出一个特定的类型。访问列表时如何指定 PlayerType?
解决方案
使用模式匹配https://docs.microsoft.com/en-us/dotnet/csharp/pattern-matching
foreach (HockeyPlayer hock in players.Where(x => x is HockeyPlayer))
{
Console.WriteLine($"{hock.Assists}");
}
或者
foreach (var player in players)
{
if (player is HockeyPlayer hockeyPlayer)
Console.WriteLine($"{hockeyPlayer.Assists}");
}
我更喜欢第二变种。
所有代码(我对其进行了一点重构):
using System;
using System.Collections.Generic;
namespace Game
{
enum PlayerType
{
HockeyPlayer,
BasketballPlayer,
BaseballPlayer
}
public abstract class Player
{
public abstract void Points();
public int PlayerId { get; set; }
public string PlayerName { get; set; }
public string TeamName { get; set; }
public int GamesPlayed { get; set; }
}
public class HockeyPlayer : Player
{
public override void Points()
{
int totalPoints = Assists + (2 * Goals);
}
public int Assists { get; set; }
public int Goals { get; set; }
}
public class BasketballPlayer : Player
{
public override void Points()
{
int totalPoints = (FieldGoals - ThreePointers) + (2 * ThreePointers);
}
public int FieldGoals { get; set; }
public int ThreePointers { get; set; }
}
public class BaseballPlayer : Player
{
public override void Points()
{
int totalPoints = (Runs - HomeRuns) + (2 * HomeRuns);
}
public int Runs { get; set; }
public int HomeRuns { get; set; }
}
class Program
{
static void ViewHockeyPlayer()
{
Console.WriteLine("View ALL hockey players");
Console.WriteLine($"{"Player Id",-15} {"Player Name",-15} { "Team Name",-15} {"Games Played",5} {"Assists",5} {"Goals",5}{Environment.NewLine}");
foreach (var player in players)
{
if (player is HockeyPlayer hock)
Console.WriteLine($"{hock.PlayerId,-15} {hock.PlayerName,-15} {hock.TeamName,-15} {hock.GamesPlayed,5} {hock.Assists,5} {hock.Goals,5}");
}
}
private static List<Player> players = new List<Player>
{
new HockeyPlayer
{
PlayerId = 1,
PlayerName = "Mitch marner",
TeamName = "Toronto Maple Leafs",
GamesPlayed = 5,
Assists = 12,
Goals = 7,
},
new BasketballPlayer
{
PlayerId = 2,
PlayerName = "Kyle Lowry",
TeamName = "Toronto Raptors",
GamesPlayed = 15,
FieldGoals = 12,
ThreePointers = 7,
},
new BaseballPlayer
{
PlayerId = 3,
PlayerName = "Jose Bautista",
TeamName = "Toronto Blue Jays",
GamesPlayed = 5,
Runs = 12,
HomeRuns = 7,
},
};
static void Main(string[] args)
{
ViewHockeyPlayer();
}
}
}
推荐阅读
- php - 在 laravel 中存储来自 foreach 循环的数组
- python-3.x - 将值传递给按钮单击事件
- kotlin - 尝试将 Kotlin 实体化类型参数与库类一起使用
- apache-zookeeper - zookeeper:线程“main”中的异常 java.lang.NoClassDefFoundError:org/apache/jute/InputArchive
- laravel - 为什么 laravel 审计不起作用?
- python - 使用 Python Azure CLI 将管道变量发送到 popen 命令
- python - 如何在 VBA Excel 中检测 shell 脚本的执行结束?
- tensorflow - 室内点云实例分割训练
- apache-flink - 从保存点恢复时避免在 Apache Flink 作业中运行初始化代码
- php - 奇怪的 PHP 的 FTP 包装器行为