3

C#,是否可以在不创建新对象变量的情况下重铸对象并访问方法和属性?

例如:

foreach (object o in collection)
{
    if (o is MyType)
        {
            (MyType)o.MyProperty = x
        }
 }

目前,我必须将 o 重新转换为 MyType [ex: MyType m = (MyType)o ] 的另一个变量,以便访问 MyType 的方法或属性。这似乎很浪费,所以我想知道我是否缺少一些允许我跳过新对象变量的声明的机制。

4

5 回答 5

4

您的代码不起作用,因为.它的优先级高于演员表。所以你需要添加括号:

foreach (object o in collection) 
{ 
    if (o is MyType) 
        { 
            ((MyType)o).MyProperty = x; 
        } 
 } 
于 2012-08-26T16:57:11.097 回答
3

您可以使用 Linq:

foreach(MyType t in collection.OfType<MyType>()) {}

您还可以使用直接投射:

foreach(object o in collection)
{
    if(o is MyType)
    {
        ((MyType)o).MyProperty = x;
    }
}

或者,如果您知道或想要确定(请记住,InvalidCastException如果集合是混合类型,则可能),您可以使用CastLinq 方法:

// If your collection is all of the same type
foreach(MyType t in collection.Cast<MyType>()) {}
于 2012-08-26T16:54:53.850 回答
2

你需要两对括号。

((MyType)o).MyProperty = x;

否则,强制转换将应用于整个表达式。


y = (MyType)o.MyMethod(x);

是相同的

y = (MyType)(o.MyMethod(x));

这不是您想要的(它会转换 的结果MyMethod)。而是写

y = ((MyType)o).MyMethod(x);
于 2012-08-26T17:00:39.167 回答
0

是的,你可以投

foreach(var t in collection.Cast<YourType>())
{
  t.MyProperty = x;
}

注意:但您必须知道,当您从引用类型传递到值类型或从值类型传递到引用类型时,装箱或拆箱操作在您的内存中是昂贵的操作。

在这种情况下,您没有此限制。

于 2012-08-26T16:56:44.703 回答
0

实现一个接口

interface MyInterface
{
 string MyProperty;
}

foreach(object o in collection)
{
MyInterface o= originalObject as MyInterface

if (MyInterface!= null)

  ((MyInterface)o).MyProperty = x;
}
于 2012-08-26T17:01:01.957 回答