C#匿名类和列表<object> </object>

时间:2013-02-06 18:07:18

标签: c# structure

我想访问List中函数返回的Structures。我无法执行此操作,因为它导致编译器错误。

public class StructTypeA
{
        public string sString1;
        public string sString2;
}
public class StructTypeB
{
        public int iNum1;
        public int iNum2;
}

public List<object> myFunction ()
{

        StructTypeA myStructA = new StructTypeA();
        StructTypeB myStructB = new StructTypeB();

        var response = new List<object> { new {oStructA = myStructA} , new {oStructB = myStructB } };

            return response;
}

public void myCallerFunction()
{
    var retVal = myFunction ();

//This does not work, it generates a compile error
// 'object' does not contain a definition for 'oStructA' and no extension method 'oStructA' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
    var myStr = retVal[0].oStructA.sString1;


//How can I access the structures.
}

我想访问oStructA和oStructB的结构,请告诉我确切的语法应该是什么。

7 个答案:

答案 0 :(得分:4)

您将返回List<object>,因此retVal[0]将是object类型,其中没有oStructA成员。

您正在创建一个包含匿名类型实例的List。您将无法通过名称在创建类型的范围之外访问这些成员。

您必须为列表创建命名类型:

class MyType
{
    public StructTypeA oStructA { get; set; }
    public StructTypeB oStructB { get; set; }
}

然后对您的方法进行编码以返回List<MyType>

创建此类型的实例就像创建匿名类型的实例一样。使用您的代码示例,只需在 new

之后添加类型名称
var response = new List<object> { new MyType {oStructA = myStructA} , new Mytype {oStructB = myStructB } };

或者您可以使用Tuple,并返回这些列表。

或者,正如其他人所说,使用dynamic。不过,我不建议这样做。命名类型可能是最好的方式。

答案 1 :(得分:2)

请在不需要时停止使用object类型和匿名类型

C#是一种类型安全的语言,这是最好的事情,所以,使用除Tuple<T1, T2>以外的类型(例如object)在可能时输入。

public List<Tuple<StructTypeA, StructTypeB>> myFunction()
{
    StructTypeA myStructA = new StructTypeA();
    StructTypeB myStructB = new StructTypeB();

    return new List<Tuple<StructTypeA, StructTypeB>> 
    {
        new Tuple<StructTypeA, StructTypeB>(myStructA, myStructB) 
    };
}

public void myCallerFunction()
{
    var retVal = myFunction();
    var oStructA = retVal[0].Item1;
}

答案 2 :(得分:1)

我想不出你为什么要这样做的实际原因,但是......

public List<dynamic> myFunction ()
{

        StructTypeA myStructA = new StructTypeA();
        StructTypeB myStructB = new StructTypeB();

        var response = new List<dynamic> { new {oStructA = myStructA} , new {oStructB = myStructB } };

            return response;
}

应该在创建匿名对象列表时执行此操作。 dynamic类型的使用可能有所帮助。

答案 3 :(得分:1)

我认为OP会做这样的事情:

public class StructTypeA
{
        public string sString1;
        public string sString2;
}
public class StructTypeB
{
        public int iNum1;
        public int iNum2;
}

public static List<object> myFunction ()
{

        StructTypeA myStructA = new StructTypeA();
        StructTypeB myStructB = new StructTypeB();

        var response = new List<object> { myStructA , myStructB };

            return response;
}

public static void Main()
{
    var retVal = myFunction ();

//This does not work, it generates a compile error
// 'object' does not contain a definition for 'oStructA' and no extension method 'oStructA' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)

    var myStr1 = ((StructTypeA)retVal[0]).sString1;
    var myStr2 = ((StructTypeB)retVal[1]).iNum1;


//How can I access the structures.
}

显然,@ Jim Mischel建议非常正确。

答案 4 :(得分:0)

您设置分组的方式,不是列表,而是元组:

StructTypeA myStructA = new StructTypeA();
StructTypeB myStructB = new StructTypeB();

var response = new List<object> { new {oStructA = myStructA} , new {oStructB = myStructB } };

列表是连续的许多项目。你有两个并排的项目。你可以这样做

List<Object> items = new List<Object>
items.Add(myStructA);
items.Add(myStructB);

现在两个项目都在列表中。但List<Object> 总是 错误。

然而,您可以将两个项目放入元组中,如:

Tuple<StuctTypeA, StructTypeB> resultSet = 
     new Tuple<StuctTypeA, StructTypeB>(myStructA, myStructB);

然后返回。

答案 5 :(得分:0)

您使用匿名对象作为列表中的项目。匿名对象旨在在单个方法的范围内使用,而不会暴露给其他方法。这样做可能,但很难并且会产生很多的问题。

从根本上说,你要做的就是从你的方法中返回两个对象。你遇到的事实是你只能返回一个对象,所以你试图解决这个问题。你的直觉是将项目放入一个列表并返回。在将对象放入列表之前,您还决定将对象放在匿名对象中。要使用更多标准编码约定来解决此问题,我们需要将方式退出。您不应该首先在此上下文中使用List

您想要创建一些可以保留这两个对象的类型;它应该有两个属性,每个对象一个。如果有一个逻辑“类型”代表这两个结构,你可以自己创建。如果这确实没有意义,并且您认为在这种情况下确实值得付出努力,您可以使用名为Tuple的现有通用持有者。

public Tuple<StructTypeA, StructTypeB> myFunction()
{
    StructTypeA myStructA = new StructTypeA();
    StructTypeB myStructB = new StructTypeB();

    return Tuple.Create(myStructA , myStructB);
}

现在从调用者的角度来看,我们知道我们正在返回一个Tuple,其中包含两个项目,第一个类型为StructTypeA,第二个类型为StructTypeB

var returnValues = myFunction();
var myStr = returnValues.Item1.sString1

答案 6 :(得分:-2)

var structA = retVal.OfType<StructTypeA>().First();
var myStr = structA.sString1;

请记住包含

using System.Linq;