如何解决c# 返回 upcasted 实例作为它的原始类型 使用泛型在调用方投射到目标类型调用方的类型检查
我正在尝试将向上转换的实例作为原始类型返回。
public class Card : MonoBehavIoUr
{
[Serializefield]
private CardInfo cardInfo;
public CardInfo Info { get => cardInfo; }
}
public abstract class CardConsumable : Card
{
}
public class CardDataBase : MonoSingleon<CardDataBase>
{
//list will contain derived class of cards as element
private List<Card> allCards = new List<Card>(100);
public dynamic GetCard(int id)
{
int count = allCards.Count;
for (int i = 0; i < count;i++)
if(allCards[i].Info.Id == id)
{
var card = allCards[i];
//tried this but got error
//var cardType = card.GetType();
//card = card as cardType;
}
return null;
}
}
例如,在 GetCard() 中,如果 id 与参数相同且其原始类型为 CardConsumable 的元素,那么我想将其作为 CardConsumable 返回 不是卡片。简而言之,我想返回实例,因为它是原始类型而不是向上转换类型
解决方法
使用泛型
除了 this answer 之外,您还可以使用 generic method 并提供您正在寻找的所需类型,并且只使用 Linq OfType
返回该类型的实例,例如
// T will be whatever type you pass in
// "where T : Card" makes sure only types derived from "Card" can be used
public T GetCard<T>(int id) where T : Card
{
return allCards.OfType<T>().SingleOrDefault(x => x.Info.Id == id);
}
当然这不是完全“动态的”,因为您需要已经知道您正在寻找的类型;)
你会这样称呼它
CardConsumable cardConsumable = cardDatabase.GetCard<CardConsumable>(id);
如果没有找到类型为 null
和 CardConsumable
的卡片,它将返回 id
。
或者例如
Card card = cardDatabase.GetCard<Card>(id);
只需要匹配 id
,但可以返回任何派生自 Card
的类型。
在调用方投射到目标类型
如果你真的想要动态运行时,你可以做同样的事情,但就像
public Card GetCard<(int id,Type type)
{
return allCards.SingleOrDefault(x => (x.GetType().IsSubclassOf(type) || x.GetType() == type) && x.Info.Id == id);
}
在这里你需要再次投射
var possiblyDynamicType = typeof (CardConsumable);
CardConsumable cardConsumable = (CardConsumable) cardDatabase.GetCard(id,typeof(possiblyDynamicType));
调用方的类型检查
或者说你每次拿到类似的卡片时都需要进行类型检查
public Card GetCard(int id) => allCards.SingleOrDefault(x => x.Info.Id == id);
然后做例如
var card = cardConsumable = cardDatabase.GetCard(id);
switch(card)
{
case CardConsumable cardConsumable:
// Do CardConsumable specific stuff
cardConsumable.Consume();
break;
case SomeOtherCardType someOtherCard:
// Do SomeOtherCardType specific stuff
someOtherCard.SomeThing();
break;
default:
// do default stuff for the rest of Card types
break;
}
,
GetCard 方法可以返回“Card”(非动态)。
然后您可以对结果使用 GetType() 或 IsAssignableFrom() 以获取派生类型并根据需要进行转换。
https://docs.microsoft.com/en-us/dotnet/api/system.type.isassignablefrom?view=net-5.0
,由于数据库中存储的所有卡片都是Card
类型,因此您可以将GetCard
方法编写为
public Card GetCard(int id) => allCards.SingleOrDefault(x => x.Info.Id == id);
然后在返回的卡片上调用 GetType()
以获取具体类型。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。