Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.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#2.0及更高版本中何时应使用“Object”?泛型是否替换对象的所有引用?_C#_.net_Generics_.net 2.0 - Fatal编程技术网

在C#2.0及更高版本中何时应使用“Object”?泛型是否替换对象的所有引用?

在C#2.0及更高版本中何时应使用“Object”?泛型是否替换对象的所有引用?,c#,.net,generics,.net-2.0,C#,.net,Generics,.net 2.0,我的同事声称,在.NET2.0及更新版本中声明变量、返回参数等时,永远不需要使用Object 他更进一步说,在所有这些情况下,都应该使用仿制药作为替代品 这项索赔是否有效?我用对象锁定并发线程…对象非常适合锁定。泛型允许您适当地键入它。您甚至可以将其约束到接口或基类。使用对象无法执行此操作 考虑这一点: void DoSomething(object foo) { foo.DoFoo(); } 没有任何铸造就不行。但是对于泛型 void DoSomething<T>(T fo

我的同事声称,在.NET2.0及更新版本中声明变量、返回参数等时,永远不需要使用
Object

他更进一步说,在所有这些情况下,都应该使用仿制药作为替代品


这项索赔是否有效?我用
对象
锁定并发线程…

对象
非常适合锁定。泛型允许您适当地键入它。您甚至可以将其约束到接口或基类。使用
对象
无法执行此操作

考虑这一点:

void DoSomething(object foo)
{
   foo.DoFoo();
}
没有任何铸造就不行。但是对于泛型

void DoSomething<T>(T foo) where T : IHasDoFoo
{
   foo.DoFoo();
}

当与COM一起使用互操作时,您并不总是有选择。。。泛型不能真正解决互操作问题


对象
也是
最轻量级的选项,如中所述。

泛型在很多情况下都胜过
对象
,但仅在类型为已知的情况下

在某些情况下,您仍然不知道类型-
对象
,或者某些其他相关的基本类型是这些情况下的答案

例如:

object o = Activator.CreateInstance("Some type in an unreferenced assembly");
您将无法强制转换该结果,甚至可能在编译时不知道该类型,因此
object
是一个有效的用法


你的同事概括得太多了——也许可以把这个问题指给他看。泛型很好,给他那么多,但它们不会“替换”对象

是的,这是有效的。已经有了一个很好的分类


但是,我无法确认是否存在您永远不会使用对象的实例,但就我个人而言,我不会使用它们,甚至在使用泛型之前,我就避免了装箱/拆箱。

有很多反例,包括您提到的使用对象进行同步的反例


另一个例子是数据绑定中使用的
DataSource
属性,它可以设置为多种不同的对象类型之一。

广泛的反例:System.Collections命名空间在.NET 4中处于活动状态,没有任何反对的迹象,也没有警告在MSDN上使用它。您在那里找到的获取和返回对象的方法。

问题中固有的方法实际上是两个问题:

  • 什么时候应该使用'Object'类型的存储位置
  • 什么时候应该使用'Object'类型的实例 显然,必须在需要保存对该类型实例的引用的任何情况下使用
    Object
    类型的存储位置(因为对此类实例的引用不能保存在任何其他类型中)。除此之外,它们还应该用于包含对没有单一有用公共基类型的对象的引用的情况。在许多使用反射的场景中(对象的类型可能取决于运行时计算的字符串),这显然是正确的,但也可以应用于某些种类的集合,这些集合中填充了在编译时已知类型的对象。作为一个简单的例子,可以通过使每个节点的类型为
    对象,并使其包含
    字符串
    对象[]
    ,来表示
    字符串
    的分层集合,该集合由
    int
    序列索引。从这样的集合中读取项目会有点笨重,因为必须检查每个项目并确定它是
    对象[]
    还是
    字符串的实例,但这种存储方法将非常节省内存,因为唯一的对象实例将是那些持有字符串或数组的实例。可以使用类型为
    String
    的字段和类型为
    Node[]
    的字段定义
    节点
    类型,甚至可以使用派生类型
    StringNode
    (包括类型为
    String
    的字段)和
    ArrayNode
    (类型为
    Node[]
    的字段)定义抽象
    节点
    类型但这种方法会增加用于保存给定数据集的堆对象的数量

    请注意,一般来说,最好设计集合,以便要检索的对象的类型不依赖于放入集合的内容(可能对不同的类型使用“并行集合”),但并非所有内容都是以这种方式在语义上工作的

    关于
    Object
    类型的实例,我不确定它们是否可以填充任何角色,而这些角色不会被一个名为
    TokenObject
    的密封类型所满足,该类型继承自
    Object
    。在许多情况下,拥有一个唯一目的是作为唯一令牌的对象实例是很有用的。从概念上讲,最好说:

    TokenObject myLock = new TokenObject; TokenObject myLock=新的TokenObject; 而不是说

    Object myLock = new Object; 对象myLock=新对象;
    因为前面的声明将明确声明的变量永远不会用于保存令牌对象以外的任何对象。尽管如此,通常的做法是在对象唯一重要的是其引用在程序的整个生命周期中都是唯一的情况下使用类型为
    Object
    的实例。

    您的同事有点太武断了。

    可能重复@vcsjones想象一下,在一个项目中,如果有很多其他类似的断言也在提出。反驳它们是令人筋疲力尽的。可能重复的Hmm,在这种情况下,我可以使用约束T:Object吗?(我从未尝试过)无约束泛型类型始终是object—它是可能的类型参数中最小的公分母。
    object
    并不是首选。这是最简单且易于使用的类型,但许多其他类型也可以使用。@Henkholtman其他类型是值还是引用有关系吗?您只能锁定引用类型。除了 Object myLock = new Object;