不知道将传入什么对象类型,如果它是 FishDTO 的类型,它有不同的路线来生成 uri,如果它不是鱼而不是哺乳动物,则应遵循标准路线。有没有更干净的方法来做到这一点?除了使用 type 有没有更好的方法使用as?这有效,但它看起来很难看:
public Uri GetAnimalImageUrl(object animalResult)
{
if (animalResult.GetType() == typeof(FishDTO))
{
return new Uri(GetFishImageUrl((FishDTO)animalResult));
}
var mammal = (MammalDTO)animalResult;
var mammalUrl = GetMammalImageUrl(mammal);
if (!string.IsNullOrEmpty(mammalUrl))
{
return new Uri(mammalUrl);
}
_logger.Error("Image not found for animal");
return null;
}
Run Code Online (Sandbox Code Playgroud)
首先,永远不要这样做:
if (animal.GetType() == typeof(Fish))
Run Code Online (Sandbox Code Playgroud)
为什么不?因为 ifanimal
是Goldfish
,是 的派生类型Fish
呢? GetType
会回来typeof(Goldfish)
。相反,请始终这样做:
if (animal is Fish fish)
Run Code Online (Sandbox Code Playgroud)
因为无论animal
是Fish
还是Goldfish
或都是如此Shark
。
其次,你的代码假设任何不是鱼的东西都是哺乳动物,但我认为鸟类、蜥蜴和甲壳类动物会不同意你的观点。面对意外输入,您的代码并不健壮。
真正的问题在这里的答案是为什么类型的形式参数object
摆在首位?这似乎是要解决的问题。如果该问题无法修复,请尽最大努力修复它:
Uri HandleFish(Fish fish) ...
Uri HandleMammal(Mammal mammal) ...
Uri HandleAnimal(Animal animal)
{
if (x is Fish fish) return HandleFish(fish);
if (x is Mammal mammal) return HandleMammal(mammal);
...
return HandleOther(x);
}
Uri HandleOther(object x) ...
Uri HandleObject(object x)
{
if (x is Animal animal) return HandleAnimal(animal);
...
return HandleOther(x);
}
Run Code Online (Sandbox Code Playgroud)
现在至少您正在使用类型系统。
或者,在较新版本的 C# 中,您可以说
switch(x)
{
case Fish fish: return HandleFish(fish);
...
Run Code Online (Sandbox Code Playgroud)
另一种方法是将逻辑放在类型层次结构本身中。
class Animal
{
public virtual Uri Handle() ...
}
class Fish : Animal
{
public override Uri Handle() ...
}
Run Code Online (Sandbox Code Playgroud)
现在如果x
是Animal
那么你只是return ((Animal)x).Handle());