2

I want to access the Structures returned by a function in a List. I am not able to do it as it is causing Compiler errors.

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.
}

I want to access the structures oStructA and oStructB, Please tell me what the exact syntax should be.


Use str_replace

$str = str_replace(array('\t','\n'),'',$str);

Or preg_replace

$str = preg_replace('/(\\\\n|\\\\t)/', '', $str);
4

7 回答 7

4

您将返回 a List<object>,因此retVal[0]将是 type 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. 不过,我一般不建议这样做。命名类型可能是最好的方法。

于 2013-02-06T18:17:39.503 回答
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;
}
于 2013-02-06T18:14:20.363 回答
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 的建议非常正确。

于 2013-02-06T18:28:39.830 回答
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可能会有所帮助。

于 2013-02-06T18:11:44.647 回答
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);

而只是返回它。

于 2013-02-06T18:11:57.930 回答
0

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

从根本上看来,您要做的只是从您的方法中返回两个对象。您遇到了只能返回一个对象的事实,因此您正试图解决这个问题。您的直觉是将这些项目放入列表并返回。您进一步决定将对象放入匿名对象中,然后再将它们放入列表中。为了使用更标准的编码约定来解决这个问题,我们需要退出。首先,您不应该List在这种情况下使用 a 。

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

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

    return Tuple.Create(myStructA , myStructB);
}

现在从调用者的角度来看,我们知道我们得到了一个Tuple有两个项目的 a,第一个是 type StructTypeA,第二个是 type StructTypeB

var returnValues = myFunction();
var myStr = returnValues.Item1.sString1
于 2013-02-06T18:23:55.003 回答
-2
var structA = retVal.OfType<StructTypeA>().First();
var myStr = structA.sString1;

记得包括一个

using System.Linq;
于 2013-02-06T18:11:56.410 回答