比使用Type更干净的方式(可能是?)-代码气味寻找更干净的方式

问题描述 投票:0回答:1

不知道将传入哪种对象类型,如果它是FishDTO类型,则它具有不同的生成uri的路径,如果它不是鱼类,而是哺乳动物,则应遵循标准路径。有没有更清洁的方法可以做到这一点?除了使用类型,还有使用as的更好方法吗?这有效,但看起来很丑:

public Uri GetAnimalImageUrl(object animalResult)
{
    if (animalResult.GetType() == typeof(FishDTO))
    {
        return new Uri(GetFishImageUrl((FishDTO)animalResult));
    }

    var mammal = (MammalDTO)animalResult;
    var mammalUrl = GetDestinationImageUrl(mammal);
    if (!string.IsNullOrEmpty(mammalUrl))
    {
        return new Uri(mammalUrl);
    }

    _logger.Error("Image not found for animal");
    return null;
}
c# object types
1个回答
1
投票

首先,永远不要这样做:

    if (animal.GetType() == typeof(Fish))

为什么不呢?因为如果animalGoldfish,则是Fish的派生类型怎么办? GetType将返回typeof(Goldfish)。相反,请始终这样做:

    if (animal is Fish)

因为无论animalFish还是GoldfishShark,都为真。

第二,您的代码假定不是鱼类的任何事物都是哺乳动物,但是我认为鸟类,蜥蜴和甲壳类动物会不同意您的看法。面对意外的输入,您的代码不够健壮。

这里要回答的真正问题是为什么首先是类型为object的形式?这似乎是要解决的问题。如果该问题无法解决,请尽力解决:

Uri HandleFish(Fish fish) ...
Uri HandleMammal(Mammal mammal) ...
Uri HandleAnimal(Animal animal) ...
Uri HandleOther(object x) ...
Uri HandleObject(object x)
{
  if (x is Fish) return HandleFish((Fish)x);
  if (x is Mammal) ...
  ...
  return HandleOther(x);
}

现在至少您正在使用类型系统。

另一种方法是将逻辑放在类型层次结构本身中。

class Animal
{
  public virtual Uri Handle() ...
}
class Fish
{
  public override Uri Handle() ...
}

现在您的方法主体为return ((Animal)x).Handle());

© www.soinside.com 2019 - 2024. All rights reserved.