Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.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
C# 4.0 在c#4中,如何避免将派生类对象指定给基类对象时类的更改?_C# 4.0 - Fatal编程技术网

C# 4.0 在c#4中,如何避免将派生类对象指定给基类对象时类的更改?

C# 4.0 在c#4中,如何避免将派生类对象指定给基类对象时类的更改?,c#-4.0,C# 4.0,C#和OOP新手你好 在c#中将派生类对象指定给基类对象时,如何避免类的更改? 在我运行下面的代码之后,我得到了这个响应 obj1是测试场。两个 obj2是测试字段。两个 我预计在分配引用后将失去对派生方法和属性的访问权(我确实这样做了),但我不希望中间代码中的类发生更改:S using System; namespace TestingField { class Program { static void Main(string[] args)

C#和OOP新手你好

在c#中将派生类对象指定给基类对象时,如何避免类的更改? 在我运行下面的代码之后,我得到了这个响应

obj1是测试场。两个
obj2是测试字段。两个

我预计在分配引用后将失去对派生方法和属性的访问权(我确实这样做了),但我不希望中间代码中的类发生更改:S

using System;

namespace TestingField
{
    class Program
    {
        static void Main(string[] args)
        {
            One obj1 = new One();
            Two obj2 = new Two();
            obj1 = obj2;
            Console.WriteLine("obj1 is {0}", obj1.GetType());
            Console.WriteLine("obj2 is {0}", obj2.GetType());
            Console.ReadLine();
        }
    }

    class One
    {
    }

    class Two : One
    {
        public void DoSomething()
        {
            Console.WriteLine("Did Something.");
        }

    }
}

GetType
是一种虚拟方法,它为您提供对象的动态类型

我想您需要变量的静态类型。通过调用变量引用的对象上的方法无法实现这一点。相反,只需写
typeof(TypeName)
,在您的例子中,这是
typeof(One)
typeof(Two)

或者,在子类中,您可以使用新方法隐藏原始方法,而不是覆盖它:

class One
{
    public string MyGetType() { return "One";  }
}

class Two : One
{
    public new string MyGetType() { return "Two"; }
}

class Program
{
    private void Run()
    {
        One obj1 = new One();
        Two obj2 = new Two();
        obj1 = obj2;

        Console.WriteLine("obj1.GetType(): " + obj1.GetType());
        Console.WriteLine("obj2.GetType(): " + obj2.GetType());
        Console.WriteLine("obj1.MyGetType(): " + obj1.MyGetType());
        Console.WriteLine("obj2.MyGetType(): " + obj2.MyGetType());
    }
}
结果:

obj1.GetType(): Two obj2.GetType(): Two obj1.MyGetType(): One obj2.MyGetType(): Two obj1.GetType():两个 obj2.GetType():两个 obj1.MyGetType():一个 obj2.MyGetType():两个
如果您是对的,您将无法访问派生类型中声明的成员,对象不会突然更改其类型或实现。您只能访问基类型上声明的成员,但派生类型的实现用于重写成员的情况,即
GetType
的情况,它是编译器生成的方法,自动重写基类的实现

扩展您的示例:

class One
{
   public virtual void SayHello()
   {
      Console.WriteLine("Hello from Base");
   }
}

class Two : One
{
    public void DoSomething()
    {
        Console.WriteLine("Did Something.");
    }
    public override void SayHello()
    {
      Console.WriteLine("Hello from Derived");
    }

}
鉴于:

One obj = new Two();
obj.SayHello(); // will return "Hello from Derived"

你还没有“换班”。变量
obj1
的类型仍然是
One
。您已将
Two
的实例分配给此变量,这是允许的,因为
Two
继承自
One
GetType
方法为您提供此变量当前引用的对象的实际类型,而不是声明的变量本身的类型。

这不是真的,typeof只对偏差有效,而不是变量。当然,您是正确的,这不是问题的重点。我的问题是,实例化对象obj1的运行时和声明的类型不同,这可能表示L2E
AddObject
方法抛出
System的问题。InvalidOperationException
-我想找不到EntityType'TestingField.obj2'的映射和元数据信息我现在明白了。在我的示例中,
obj1.GetType()
obj2.GetType()
实际上都是类2的成员。我想我的问题应该是“如何防止在将派生类对象引用指定给基类对象引用时使用派生成员?”