我唯一一次尝试使用对象是List<object>
,我后悔并重写了它。我永远找不到使用对象而不是接口的实例。什么时候在 .NET 中使用对象?
9 回答
坦率地说,你真的需要它并不经常发生。但是当你这样做时,它很明显。反射、泛型类型转换、序列化或标记是最终拥有对象的主题。
就像void*
……本质上几乎是一样的。您想知道这种“粗制滥造”的物品有什么用,直到您最终陷入无路可走的角落,只能使用它。
这是您在托管代码中可以找到的最低级别。一切都是对象,你无法深入。
通用类型转换:
public T AddComponents<T>()
{
Component component = (Component)Activator.CreateInstance(typeof(T));
if (component != null)
{
component.Parent = this;
components.Add(component);
}
return (T)(object)component; //Cannot directly cast Component to T since we have no constraint between them.
}
将项目分配给不知道内容的通用容器的想法的“标签”:
public class DragDropWrapper
{
private object tag;
public object Tag
{
get { return tag; }
}
}
什么是拖?不知道。可以是任何东西。
或者非常常见的事件发送者:
public void Message(object sender, string text)
{
Entry entry = new Entry(sender, EntryType.Message, text);
AddEntry(entry);
}
发件人可以是任何东西。
扩展对象属性的反射:
public static List<InfoNode> ExpandObject(InfoGrid grid, InfoNode owner, object obj)
{
List<InfoNode> nodes = new List<InfoNode>();
if (obj == null)
return nodes;
PropertyInfo[] infos = obj.GetType().GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public);
foreach (PropertyInfo info in infos)
nodes.Add(new PropertyNode(grid, owner, obj, info));
nodes = nodes.OrderBy(n => n.Name).ToList();
return nodes;
}
还有更多的可能性。
嗯,一个很好的例子。假设您想编写一个库,并且该库需要能够获取一些任意数据并存储它。例如,就像在 ORM 中那样,您可能会编写这样的函数..
bool InsertObject(object item);
对象序列化器也是如此。想想 JSON。
基本上,当您需要以非常通用的方式工作时,您会“使用”对象。
当您需要存储对任何对象类型的引用时,您可以使用对象。如果这是您不需要做的事情,请随意不要使用它。
As object
can be used to reference any value, you use it when you need to do exactly that.
The String.Format
method for example uses object
parameters to be able to put any value in a string:
public string Format(string format, params object[] parameters)
That enables you to send any values into it, for example:
String.Format("{0} {1}", 1, "2");
Using it as a generic type, like in List<object>
, is not so common as you usually have some more specific type that you can use. However, a List<object>
would be the generic equivalent of the ArrayList
class, which was frequently used before generics was introduced in .NET.
人们很少直接使用对象,因为它的功能太少了。它在 V 1.0(泛型之前)中使用得更频繁,但现在很少用于比偶尔的 doble cast 更多的地方,如下所示:
(A)(object)someType;
解决铸造操作的限制。
的真正目的object
是强制执行基本操作,例如GetType()
and ToString()
,并提供这些操作的默认实现。
例如,我将它用作类中的锁定变量
通常,只有在与在泛型添加到 C# 语言之前编写的 API 交互时,您才会主要显式使用对象类型。
我发现相当普遍的一个用例是以下成语:
class NeedsToBeThreadSafe {
private static object _lock = new object();
void ThreadSafeOperation() {
lock (_lock)
{
// Perform some useful work
}
}
}
在这里,我们_lock
只需要对象来实现锁定;它不需要任何成员或值——所以object
类型是合适的。
Object 是所有类型的父类型。您从 .Net 框架创建或使用的每个类型都继承自它。在 .Net 中引入泛型之前,大多数集合类型(例如 System.Collecrtions 下的 ArrayList)被定义为接受对象类型。这意味着您可以添加不同类型的混合包。并且您需要在检索时将项目转换为特定类型。这是不必要的开销。
回答你的问题。您应该避免在任何地方使用对象,因为它对您的代码没有任何好处。引入泛型的全部目的是摆脱对象表示法,因此您可以避免代码中不需要的强制转换。
Object
可以在您创建的 API 不关心底层类型或可以接受所有内容时使用。例如,我想创建一个序列化所有内容的库。在这种情况下,库方法会接收 的实例object
,并可以通过反射处理其余部分。
或者假设您想创建一个接收成员访问 lambda 表达式的重构友好方法,如下所示:
f(something, s => s.member);
而且您不关心成员类型可能是什么,它可能是任何东西。您可以定义如下方法:
void f(SomeType something, Expression<Func<SomeType, object>>) ...
其他常见用途是将其用作线程锁变量,其他人已经提到过。