为什么需要显式铸造? [英] Why is explicit casting required?

查看:109
本文介绍了为什么需要显式铸造?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好朋友,



为什么要将派生类型转换为基类型时需要显式强制转换,从某种意义上讲:

派生d =(衍生)基数;

但如果我反之亦然,则不需要这样的东西。如下所示:

Base b = new Derived();





非常感谢,
Rahul

解决方案

您正在触及向上和向下投射的主题。让我们看一些示例:

  public   class  MyBase 
{
public String 名称;

public virtual void Log()
{
Console.WriteLine( String .Format( 我的名字是{0},Name));
}
}

public class MyClassA: MyBase
{
public int 大小;

public 覆盖 void Log()
{
base .Log();
Console.WriteLine( String .Format( 我的尺寸为{0},尺寸));
}
}

public class MyClassB: MyBase
{
public int 颜色;

public 覆盖 void Log()
{
base .Log();
Console.WriteLine( String .Format( 我的颜色是{0},颜色));
}
}



你可以看到任何派生类的实例总是包含完整版的基类,所以那里没有必要告诉编译器如何转换它。它被称为向下转换,总是可以毫无问题地完成。

另一方面,对基类的引用也可以引用MyBase,NyClassA或MyClassB的实际实例,所以如果你想要将它分配给MyClassA,你必须告诉编译器你知道你在说什么 - 这叫做up-casting并且必须明确说明......


添加到解决方案1和2:



这些投射规则的原因是一些额外的成员被添加到派生类中。考虑一下:

  class 基数{
内部 int A { get ; set ; }
}

class 派生:基础{
internal int B { get ; set ; }
}

class AnotherDerived:Base {}





如您所知,有实例属性 Base.A Derived.A AnotherDerived.A Derived.B 。而且,重要的是,没有 AnotherDerived.B



成像,例如,您可以成功分配

  //  将无法编译: 
派生派生= AnotherDerived ();
// 它可以让您访问derived.B:
派生。 B = 13 ; // 灾难:访问不存在的成员





它可以让你访问 derived.B ,这反过来又可以访问不存在的成员,因为运行时类型实际上是 AnotherDerived 。这就是使用动态演员的原因:

 Base @object =  new   //   ......某事 

// ...

派生派生= @object 派生;
如果(派生!= null / / 否则B不存在
derived.B = 15 ;



请注意,作为OOP的一部分,动态类型检查和转换的实际使用被视为违反OOP。实际上,如果您有这样的需求,它表明对象层次结构没有合理的计划。但是,有一些罕见的合理排除。它们在罕见时才合理。你的代码不应该基于它。



参见:

http://msdn.microsoft.com/en-us/library/cscsdfbt.aspx [ ^ ],

http://msdn.microsoft.com/en-us/library/scekt9xw.aspx [ ^ ]。



< dd> -SA


在这里提出这样的问题没什么意义 - 更好地阅读一本关于基本OOP概念和C#的书(也许还有趣的协方差与逆变 - )< a href =http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx> http://blogs.msdn.com/b/csharpfaq /archive/2010/02/16/covariance-and-contravariance-faq.aspx [ ^ ]



但快速回答:派生类型IS的实例也始终是基类型的实例。所以对于类型引擎,这总是有效的,因为基类只有一个有效的路径(所有派生类也是它们基类的有效实例,因此强制转换永远不会失败 - 因此不需要) 。但是对于相反的情况,类型引擎应该如何知道基类型的实例完全是派生类型 - 对于给定的基类型可能有许多派生类型 - 因此需要显式转换(并且可能失败)。 / BLOCKQUOTE>

Hello friends,

Why is an explicit cast required when you want to cast a derived type to a base type, In the sense :
Derived d = (Derived) Base;
But if i do vice versa nothing like this is required. Like below:
Base b = new Derived();


Thanks a ton,
Rahul

解决方案

You are touching the subject of up- and down-casting. Let see some sample:

public class MyBase
{
  public String Name;

  public virtual void Log( )
  {
    Console.WriteLine(String.Format("My name is {0}", Name));
  }
}

public class MyClassA : MyBase
{
  public int Size;

  public override void Log( )
  {
    base.Log();
    Console.WriteLine(String.Format("My size is {0}", Size));
  }
}

public class MyClassB : MyBase
{
  public int Color;

  public override void Log( )
  {
    base.Log();
    Console.WriteLine(String.Format("My color is {0}", Color));
  }
}


You can see that an instance of any of the derived classes always will contain a full version of the base class, so there is no need to tell the compiler how to cast it. It's called down-casting and always can be done without problem.
On the other side a reference to a base class can hold reference to an actual instance of MyBase, NyClassA or MyClassB too, so if you want to assign it to MyClassA you have to tell the compiler that you know what are you talking about - this called up-casting and must be explicitly stated...


To add to the Solutions 1 and 2:

The reason for these casting rule is some extra members added to the derived class. Consider this:

class Base {
    internal int A { get; set; }
}

class Derived : Base {
    internal int B { get; set; }
}

class AnotherDerived : Base { }



As you understand, there are instance properties Base.A, Derived.A, AnotherDerived.A and Derived.B. And, importantly, no AnotherDerived.B.

Imaging, for example, that you could have successful assignment

// will not compile:
Derived derived = new AnotherDerived(); 
// it would give you access to derived.B:
derived.B = 13; // disaster: access to non-existing member



It would give you access to derived.B, which is, in turn, would be the access to non-existing member, because runtime type is actually AnotherDerived. That's why the dynamic cast is used:

Base @object = new //... something

//...

Derived derived = @object as Derived;
if (derived != null) // otherwise B does not exist
   derived.B = 15;


Note that the actual use of dynamic type check and casting, being a part of OOP, is considered as violation of OOP. Indeed, if you have such need, it suggests that the object hierarchy is not reasonably planned. There are rare reasonable exclusions though. They are only reasonable when they are rare. Your code should not be fundamentally based on it.

See also:
http://msdn.microsoft.com/en-us/library/cscsdfbt.aspx[^],
http://msdn.microsoft.com/en-us/library/scekt9xw.aspx[^].

—SA


Makes not much sense to ask such questions here - better read a book about Basic OOP concepts and C# (maybe also interesting covariance vs. contravariance- )http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx[^]

But a quick answer: An instance of a derived type "IS" always also an instance of the base type. So for the "type engine" this always works because there is only one valid "path" to the base class (all derived classes are also valid instances of their base class, so a cast could NEVER fail - and isn't needed therefore). But for the opposite case, how should the type engine know that the instance of your base type is exactly of the derived type - there could be many derived types for a given base type - so explicit casting is needed (and may fail).


这篇关于为什么需要显式铸造?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆