为什么我得到异常InvalidCastException

本文关键字:异常 InvalidCastException 为什么 | 更新日期: 2023-09-27 18:17:46

留言:

无法强制转换类型为"Microsoft.Xna.Framework.Graphics"的对象。"Microsoft.Xna.Framework.Graphics.BasicEffect"

代码:

foreach (ModelMesh mesh in xwingModel.Meshes)
            {
                // This is where the mesh orientation is set, as well 
                // as our camera and projection.
                foreach (BasicEffect Effects in mesh.Effects)
                {
                    Effects.EnableDefaultLighting();
                    Effects.World = transforms[mesh.ParentBone.Index] *
                        //Matrix.CreateRotationY(modelRotation)
                         Matrix.CreateTranslation(modelPosition);
                    Effects.View = Matrix.CreateLookAt(cameraPosition,
                        Vector3.Zero, Vector3.Up);
                    Effects.Projection = Matrix.CreatePerspectiveFieldOfView(
                        MathHelper.ToRadians(45.0f), aspectRatio,
                        1.0f, 10000.0f);
                }
                // Draw the mesh, using the effects set above.
                mesh.Draw();
            }

例外是在这部分:

BasicEffect影响

完整异常消息:

System.InvalidCastException was unhandled
  HResult=-2147467262
  Message=Unable to cast object of type 'Microsoft.Xna.Framework.Graphics.Effect' to type 'Microsoft.Xna.Framework.Graphics.BasicEffect'.
  Source=MyFlightSimulator
  StackTrace:
       at MyFlightSimulator.Game1.DrawModel() in Game1.cs:line 279
       at MyFlightSimulator.Game1.Draw(GameTime gameTime) in Game1.cs:line 133
       at Microsoft.Xna.Framework.Game.DrawFrame()
       at Microsoft.Xna.Framework.Game.Tick()
       at Microsoft.Xna.Framework.Game.HostIdle(Object sender, EventArgs e)
       at Microsoft.Xna.Framework.GameHost.OnIdle()
       at Microsoft.Xna.Framework.WindowsGameHost.RunOneFrame()
       at Microsoft.Xna.Framework.WindowsGameHost.ApplicationIdle(Object sender, EventArgs e)
       at System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FDoIdle(Int32 grfidlef)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at Microsoft.Xna.Framework.WindowsGameHost.Run()
       at Microsoft.Xna.Framework.Game.RunGame(Boolean useBlockingRun)
       at Microsoft.Xna.Framework.Game.Run()
       at MyFlightSimulator.Program.Main(String[] args) in Program.cs:line 15
  InnerException: 

Game1第279行是:

foreach (BasicEffect Effects in mesh.Effects)

程序第15行是:

game.Run();

完整的方法代码:

private void DrawModel()
        {
            Matrix[] transforms = new Matrix[xwingModel.Bones.Count];
            xwingModel.CopyAbsoluteBoneTransformsTo(transforms);
            // Draw the model. A model can have multiple meshes, so loop.
            foreach (ModelMesh mesh in xwingModel.Meshes)
            {
                // This is where the mesh orientation is set, as well 
                // as our camera and projection.
                foreach (BasicEffect Effects in mesh.Effects)
                {
                    Effects.EnableDefaultLighting();
                    Effects.World = transforms[mesh.ParentBone.Index] *
                        //Matrix.CreateRotationY(modelRotation)
                         Matrix.CreateTranslation(modelPosition);
                    Effects.View = Matrix.CreateLookAt(cameraPosition,
                        Vector3.Zero, Vector3.Up);
                    Effects.Projection = Matrix.CreatePerspectiveFieldOfView(
                        MathHelper.ToRadians(45.0f), aspectRatio,
                        1.0f, 10000.0f);
                }
                // Draw the mesh, using the effects set above.
                mesh.Draw();
            }
        }

为什么我得到异常InvalidCastException

部分或全部网格元素。Effects不是BasicEffect,而是Effect对象

Try this

foreach (Effect ItemEffect in mesh.Effects)
{
   if ( (ItemEffect is BasicEffect) == false)
       continue;
    BasicEffect Effects = (BasicEffect)ItemEffect;
    Effects.EnableDefaultLighting();
    Effects.World = transforms[mesh.ParentBone.Index] *
    Matrix.CreateTranslation(modelPosition);
    Effects.View = Matrix.CreateLookAt(cameraPosition,Vector3.Zero, Vector3.Up);
    Effects.Projection = Matrix.CreatePerspectiveFieldOfView(
                    MathHelper.ToRadians(45.0f), aspectRatio,
                    1.0f, 10000.0f);
}

如本文所述:XNA在BasicEffect上应用效果并非所有效果都是BasicEffects。

foreach(BasicEffect basicEffect in mesh.Effects.OfType<BasicEffect>())
{
}

mesh.Effects中包含什么类型的对象?从MSDN文档中,BasicEffect继承自Effect,因此如果mesh.Effects中的所有元素都是BasicEffect类型,则代码应该可以工作。

mesh.Effects中的元素很可能是而不是 BasicEffect

仔细检查列表中的内容,或者确保您只在BasicEffect上运行代码,使用as操作符强制转换它们并检查它们是否为空,在这种情况下它们是BasicEffect

foreach (BasicEffect Effects in mesh.Effects)
{
     BasicEffect basicEffect = Effects as BasicEffect;
     if (basicEffect != null)
     {
          //Effects is a BasicEffect, run code on basicEffect
     }
}

你也可以使用LINQ的OfType来选择网格中BasicEffect s的效果

foreach (BasicEffect Effects in mesh.Effects.OfType<BasicEffect>());
{
     //Run code on Effects
}

并不是集合的每个成员都可以转换为BasicEffect,但是你可以避免它们:

foreach(var effect in mesh.Effects.Where(e => e.GetType().IsAssignableFrom(Effect).ToList())
    YourFunctionOrWhatever();

如果你正在读这篇文章,看看马丁的回答。它更漂亮了:)