Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我应该使用(ObjectType)还是';作为对象类型';用c#铸造时?_C#_Casting - Fatal编程技术网

我应该使用(ObjectType)还是';作为对象类型';用c#铸造时?

我应该使用(ObjectType)还是';作为对象类型';用c#铸造时?,c#,casting,C#,Casting,可能重复: 比如说,我有一个名为MyObjectType的类,我想将事件的sender参数转换为这种类型。我通常会简单地这样做: MyObjectType senderAsMyType = (MyObjectType) sender; 我最近意识到也可以这样做: MyObjectType senderAsMyType = sender as MyObjectType; 哪种方式最有效?因此,我可以使我的代码保持一致,并在整个过程中使用其中一种方法。或者他们都有赞成和反对的意见?如果有的话,

可能重复:

比如说,我有一个名为MyObjectType的类,我想将事件的sender参数转换为这种类型。我通常会简单地这样做:

MyObjectType senderAsMyType = (MyObjectType) sender;
我最近意识到也可以这样做:

MyObjectType senderAsMyType = sender as MyObjectType;
哪种方式最有效?因此,我可以使我的代码保持一致,并在整个过程中使用其中一种方法。或者他们都有赞成和反对的意见?如果有的话,请有人告诉我


再次感谢,

如果您希望避免任何
无效的例外情况,请使用

MyObjectType senderAsMyType = sender as MyObjectType;
否则使用

MyObjectType senderAsMyType = (MyObjectType)sender;
如果
InvalidCastException
代表应用程序中真正的异常情况

至于表现,我认为你不会发现这两种不同类型的演员之间有明显的区别。但我很感兴趣,因此我使用并获得了证实我怀疑的结果:

测试:

using System;
using BenchmarkHelper;

class Program
{
    static void Main()
    {
        Object input = "test";
        String output = "test";

        var results = TestSuite.Create("Casting", input, output)
            .Add(cast)
            .Add(asCast)
            .RunTests()
            .ScaleByBest(ScalingMode.VaryDuration);
        results.Display(ResultColumns.NameAndDuration | ResultColumns.Score,
                results.FindBest());
    }

    static String cast(Object o)
    {
        return (String)o;
    }

    static String asCast(Object o)
    {
        return o as String;
    }

}
============ Casting ============
cast   30.021 1.00
asCast 30.153 1.00
输出:

using System;
using BenchmarkHelper;

class Program
{
    static void Main()
    {
        Object input = "test";
        String output = "test";

        var results = TestSuite.Create("Casting", input, output)
            .Add(cast)
            .Add(asCast)
            .RunTests()
            .ScaleByBest(ScalingMode.VaryDuration);
        results.Display(ResultColumns.NameAndDuration | ResultColumns.Score,
                results.FindBest());
    }

    static String cast(Object o)
    {
        return (String)o;
    }

    static String asCast(Object o)
    {
        return o as String;
    }

}
============ Casting ============
cast   30.021 1.00
asCast 30.153 1.00

我认为这个答案将有助于


基本区别:如果
sender
不是
MyObjectType
的实例或其子类之一,则第一个示例(直接转换)抛出异常;第二个(as运算符)返回null

它们都不是明显的好或坏;根据你目前面临的情况,你应该使用其中一种。如果
sender
不是
MyObjectType
您想做什么?可能,在本例中,因为它是一个事件处理程序,所以抛出异常非常好…

您应该尽可能使用
(MyObjectType)
,因为如果强制转换失败,您将立即得到异常。使用
as
以后,您可能会在任何地方出现NullRef异常。

只有在处理完失败的强制转换后,才使用
as

他们做的事情略有不同。这取决于你想要什么

// Will throw an exception if the cast cannot be made
MyObjectType foo = (MyObjectType)bar; 

你用哪个取决于你?如果您预计强制转换可能会频繁失败(您对此很满意),请选择
作为
,然后测试null,如果您预计强制转换永远不会失败,请选择
(键入)


请记住,如果引用可以是
null
,并且您也需要知道这一点,那么在播放之前测试
null

不要太担心效率,最好根据语义做出决定。一种方法是否比另一种方法更有效在很大程度上取决于具体情况,以及您期望它失败多少次

直接强制转换“(ObjectType)”可能会失败,并将抛出InvalidCastException

“as”不会因异常而失败,但如果强制转换不起作用,则会返回null对象

如果强制转换确实有效,只需执行强制转换即可。这样,如果事情出了问题,你将得到例外,希望能够解决问题

如果您不确定对象类型,那么使用“as”并检查null可能会很有用

MyObjectType senderAsMyType = (MyObjectType) sender;
MyObjectType senderAsMyType = sender as MyObjectType;

if(senderAsMyType != null)
{
    senderAsMyType.MyMethod()
}
如果无法将发送方强制转换为
MyObjectType
,这将抛出一个
InvalidCastException

MyObjectType senderAsMyType = sender as MyObjectType;
如果无法将发件人强制转换为
MyObject
,则
senderAsMyType
将为
null
。此方法不能与值类型一起使用


我相信后者的速度稍微快一点,但差别实际上是微不足道的。

这取决于你对目标的期望。如果对象应为该类型,并且您需要访问该对象成员,请使用:

MyObjectType senderAsMyType = (MyObjectType) sender;
如前所述,如果无效,则会为您抛出一个InvalidCastException

如果它可能是那种类型,并且您只想在它是的情况下采取行动,请使用“as”,并检查null

MyObjectType senderAsMyType = (MyObjectType) sender;
MyObjectType senderAsMyType = sender as MyObjectType;

if(senderAsMyType != null)
{
    senderAsMyType.MyMethod()
}
但是,如果只检查类型,而不需要对象,请使用“is”运算符,因为这将是最便宜的资源

if(sender is MyObjectType)
    //do something

从最佳实践的角度来看,如果您希望得到不同类型的对象,并且您的代码可以处理它们,那么您应该使用
作为
关键字,例如

public void MyFunction(MyObject obj)
{
  obj.DoSomething();
  SpecializedObject specialized = obj as SpecializedObject;
  if(specialized!=null)
  {
    specialized.DoSthSpecial();
  }
}
当您确定类型将是您期望的类型时,请使用普通转换,因为技术原因,您只需要转换它:

XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyObject));
MyObject obj = (MyObject)xmlSerializer.Deserialize(xml);

这样不仅更快,而且不会隐藏错误。

Aah抱歉,我搜索时找不到答案。Thanks我认为速度是非常主观的,并且会受到你期望的铸造失败百分比的影响。一个没有人提到的重要一点是铸造和“as”不做相同的事情。例如,如果您有一个用户定义的从Foo到Bar的显式转换,那么“(Bar)Foo”调用转换方法,但“Foo as Bar”不调用。确保你选择了真正符合你要求的选项。使它正确,然后把它弄清楚,然后才考虑使它更快。