什么是铸造参数的成本

kla*_*ist 7 c# casting

当使用MVVM和Prism时,我发现自己进行了大量的转换,因为大多数参数都是接口

防爆

  public void AddCrSubSystemsToPlant(IPlantItem plantItm, CRArticleItem crItm)
        {

            OSiteSubSystem itm = (OSiteSubSystem)crItm;
            itm.PartData.Order = ((OSiteEquipment)plantItm).SubSystems.Count() + 1;

            ((OSiteEquipment)plantItm).SubSystems.Add(itm);

        }
Run Code Online (Sandbox Code Playgroud)

要么

  public void DeletePart(IPlantItem plantItem)
        {
            IEnumerable<IPlantItem> itmParent = GetParentPartByObjectId(_siteDocument, plantItem);

            if (plantItem is OSiteEquipment)
            ((ObservableCollection<OSiteEquipment>)itmParent).Remove((OSiteEquipment)plantItem);

            if (plantItem is OSiteSubSystem)
                ((ObservableCollection<OSiteSubSystem>)itmParent).Remove((OSiteSubSystem)plantItem);

            if (plantItem is OSiteComponent)
                ((ObservableCollection<OSiteComponent>)itmParent).Remove((OSiteComponent)plantItem);
        }
Run Code Online (Sandbox Code Playgroud)

我的问题是,涉及的费用是多少.如果避免,这些操作是否会耗费大量内存或CPU.

任何意见?

cad*_*ll0 7

我认为更重要的问题是你为什么要做这么多的演员?

在第一个示例中:如果继续将其转换
为第一个参数类型,为什么?关于第二个参数也可以这样说.IPlantItemOSiteEquipment

在第二个例子中:
为什么GetParentPArtByObjectId返回IEnumerable<IPlantItem>?如果要返回一个ICollection<IPlantItem>你就不必投了ObservableCollection<T>. ObservableCollection<T>继承从Collection<T>哪个实现ICollection<T>ICollection.您应该能够从集合中删除该项目,甚至不知道它的类型.

现在有些建议.
不要多次投射同一个物体.
不要这样做:

if (obj is IPlantItem)
    ((IPlantItem)obj).DoSomething();
Run Code Online (Sandbox Code Playgroud)

这样做

IPlantItem plant = obj as IPlantItem;
if (plant != null)
    plant.DoSomething();
Run Code Online (Sandbox Code Playgroud)

尽可能使用基类型.这将使你不必投这么多.如前所述,不要强制转换ObserableCollection<T>为调用方法ICollection

使用泛型.如果需要特定于类型的逻辑,请使用泛型参数创建一个抽象基类(如果不需要任何共享逻辑,则只是一个接口).然后为接口的每个实现制作该类的实现.方法也可以是通用的.我可以将第二个例子重写为

public void DeletePart<TPlantItem>(TPlantItem plantItem)
    where TPlantItem : IPlantItem
{
    IEnumerable<TPlantItem> itmParent = GetParentPartByObjectId(_siteDocument, plantItem);
    ((ObservableCollection<TPlantItem>)itmParent).Remove(plantItem);
}
Run Code Online (Sandbox Code Playgroud)