(C#)为什么Visual Studio说它是一个对象,而GetType表示它是一个Func< object&gt ;? [英] (C#) why does Visual Studio say it's an object while GetType says it's a Func<object>?

查看:160
本文介绍了(C#)为什么Visual Studio说它是一个对象,而GetType表示它是一个Func< object&gt ;?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C#新手问题在这里。以下代码(摘自Christian Gross,Apress的C#从新手到专业一书)给出了一个错误:

 工作表.Add(C3,CellFactories.DoAdd(worksheet [A2],worksheet [B1])); 

原因是方法 DoAdd()不接受给定的参数。

  public static Func< object> DoAdd(Func< object> cell1,Func< object> cell2){...} 

上面的方法调用中的两个参数都是 object 类型,而该方法只接受 Func< object> 。但两个工作表元素的都是 Func< object>

  worksheet.Add(A2,CellFactories.Static(10.0)); 

其中静态方法只返回给定的值:

  public static Func< object>静态(对象值){return()=>值; } 
// return type = Func< object>

当我铸造工作表[A2] as Func< object> ,代码确实有效。但是有一些我不明白。对象实例的类型是 Func< object> 。我已经使用了 GetType()方法来查看这个证明,并将原始元素的对象类型与cast对象(可以接受)进行比较: p>

  Console.Writeline(工作表[A2] .GetType()); 

//现在转换为正确的类型(为什么它不能隐式地,btw?)
Funk1 = worksheet [A2]作为Func< object>;

Console.Writeline(Funk1.GetType());

..并且它们都是相同的! (Type = System.Func'1 [System.Object]

即使当我使用 .Equals()方法比较两种类型,它返回 true



然而,VS在方法调用中将第一个对象实例看作类型 object 。为什么?为什么被调用的方法将参数视为与GetType()返回的不同类型的参数?
(如果是这样, GetType()方法有什么好处?)

非常感谢为您的建议/意见! (如果书中的例子给出错误并且你没有看到原因,那么学习这门语言有点难,因此,得到了一个模糊的印象,即使用 GetType()

解决方案

您需要了解动态类型静态输入。您的工作表对象的索引器很可能具有静态类型 object

  public object this [string cell] {get {...} set {...}} 

由于C#中的所有对象都是继承,因此所有对象都必须继承从类型 object ,存储在单元格中的对象引用可以是对任何对象的引用。



也就是说,因为委托(例如 Func< T> 是,所以对象,它可以存储在对象引用中:

 函数功能<对象> func =()=> returnfoo; 
对象o = func; //这个编译好的

编译器可以完全理解这一点,因为它隐含地理解派生类可以存储在对基类的引用中。



编译器无法自动执行的操作是确定动态类型或运行时类型

em>

  Func< object> func =()=> returnfoo; 
对象o = func; //编译好的
func = o; //< - 错误

编译器不知道存储在 o 中的对象实际上是类型 Func< object> 。它不应该跟踪这个。这是必须在运行时检查的信息。

  func =(Func< object>)o; // 好! 

上述代码行编译成与以下行为类似的行为:

  if(o == null)
func = null;
else if(typeof(Func< object>)。IsAssignableFrom(func.GetType()))
__copy_reference_address __(func,o); //组成功能!演示只有
else引发新的InvalidCastException();

通过这种方式,可以在运行时检查任何转换(从一种类型转换为另一种类型)到确保它是有效和安全的。


C# newbie question here. The following code (taken from the book "C# From Novice to Professional" by Christian Gross, Apress) gives an error:

worksheet.Add("C3", CellFactories.DoAdd(worksheet["A2"], worksheet["B1"]));

The reason is that the method DoAdd() does not accept the given arguments.

public static Func<object> DoAdd(Func<object> cell1, Func<object> cell2) {...}

VS claims that both args in the method call above are of type object whereas the method accepts only Func<object>. But the value of both worksheet elements is of type Func<object>:

worksheet.Add("A2", CellFactories.Static(10.0));

where this Static method just returns the given value:

public static Func<object> Static(object value) { return () => value; }
// return type= Func<object>

When I cast worksheet["A2"] as Func<object>, the code does work.

But there is something I don't understand. The type of the object instance is Func<object>. I have used the GetType() method to see proof of this, and compare the object types of the original elements to that of the cast object (which IS accepted):

Console.Writeline(worksheet["A2"].GetType());

// now cast to the correct type (why can't it do that implicitly, btw?)
Funk1 = worksheet["A2"] as Func<object>;

Console.Writeline(Funk1.GetType());

.. and they are ALL identical! (Type = System.Func'1[System.Object])

And even when I use the .Equals() method to compare both types, it returns true.

Yet, VS sees the first object instance as type object in the method call. Why? Why does the called method 'see' the argument as a different type than the GetType() returns? (and if so, what good is the GetType() method?)

Thanks a lot for your advice/comments! (It's kinda hard to learn the language if the book examples give an error and you don't see the reason - hence, got the vague impression that something is wrong either with GetType() or VS.)

解决方案

You need to understand the difference between dynamic typing and static typing. The indexer for your worksheet object most likely has a static type of object.

public object this[string cell]{get{...}set{...}}

Because all objects in C# inherit from type object, the object reference stored in a cell can be a reference to any object.

That is, because a delegate (such as Func<T>) is an object, it can be stored in an object reference:

Func<object> func = ()=>return "foo";
object o = func; // this compiles fine

And the compiler can figure this all out, because it understands implicitly that a derived class can be stored in a reference to a base class.

What the compiler cannot do automatically, is determine what the dynamic type, or run time type of an object is.

Func<object> func = ()=>return "foo";
object o = func; // this compiles fine
func = o; // <-- ERROR

The compiler doesn't know that the object stored in o is actually of type Func<object>. It's not supposed to keep track of this. This is information that must be checked at run time.

func = (Func<object>)o; // ok!

The above line of code compiles into something that behaves similarly to this:

if(o == null)
    func = null;
else if(typeof(Func<object>).IsAssignableFrom(func.GetType()))
    __copy_reference_address__(func, o); // made up function!  demonstration only
else throw new InvalidCastException();

In this way, any cast (conversion from one type to another) can be checked at run time to make sure it's valid and safe.

这篇关于(C#)为什么Visual Studio说它是一个对象,而GetType表示它是一个Func&lt; object&gt ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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