2013-10-31 31 views
0

我有一个功能,是需要自定义数据类型的,单程 解决这个问题是通过定义一个结构然而,这仅仅是对 只是一个功能,那岂不是更好,如果我只是使用一个动态的 对象呢?我应该为一个函数的唯一目的定义一个结构吗?

例如:

public struct myDataType(){ 
    public string name { get; set; } 
    public string email { get; set; } 
    public string token { get; set; } 
} 

public bool doSomething(string name, string email, string token){ 
    myDataType MDT = new myDataType(); 
    MDT.name = name; 
    MDT.email = email; 
    MDT.token = token; 
    //Do something with MDT 
    return 1; 
} 

或者

public bool doSomething(string name, string email, string token){ 
    dynamic MDT = new ExpandoObject(); 
    MDT.name = name; 
    MDT.email = email; 
    MDT.token = token; 
    //Do something with MDT 
    return 1; 
} 

注:

  1. 虽然我可以在结构中定义所有可能的道具,但我不知道我需要使用多少道具。

  2. 的实施例是不是真正的只是示出了2点可能的方法。

+5

为什么你很确定你不能在其他地方使用该结构? (你已经在两个地方使用它,因为它是一个返回值) –

+0

你的代码没有意义。第二个例子不会编译,并且意味着函数的使用方式有所不同。 – Euphoric

+0

@Tim Schmelter,实际上结构必须在其他地方使用,因为它是返回值。调用该方法的代码也将使用它。 – acfrancis

回答

2

这不是dynamic目的。只有在运行时才知道该类型(并且有充足的理由来实现这种情况),就会使用Dynamic。除此之外的用法只是强调C#的强类型本质,允许编译代码,在运行时可能无效。

如果您需要具有属性B,C,D的对象A,那么即使您打算使用它一次,也要创建该对象。此外,当某些事情调用你的函数并需要访问返回对象的属性时,你将需要使用该对象。这些属性最好是已知和强类型的。如果您愿意,您可以使用结构而不是类,但将其设为强类型对象。

编辑:原始问题被编辑以表明函数不返回对象。尽管如此,上述情况仍然如此 - 也就是说,这是而不是这种情况下,直到运行时才知道类型,因此它是而不是正确的情况下使用dynamic。由于对象的使用寿命很短,我会使用struct。请参阅此处深入讨论何时应使用structWhen to use struct?

+0

这就是我的情况,因为虽然我可以在结构中定义所有可能的道具,但我可能最终只会使用2或3个道具,所以我真的不知道我需要多少道具,那才合格? –

+0

我会再次编辑我的问题以使其更清楚。 –

+1

我想说,如果没有更多地了解你对对象所做的事情的背景很难说。虽然我同意为了使用其中一个或两个而定义一打属性似乎并不是最实际的方法,但我不相信“动态”必然是。例如,其中一个属性可以是泛型类型吗? 'struct Foo {public T Property {get;设置}}。你对这个对象的使用会真正影响构建它的最佳方式。 – mayabelle

0

如果您选择所提出的两种解决方案中的任何一种,则不会影响性能。

当编译器符合dynamic关键字时,它将执行相同的操作,将定义一个包含所有已定义成员的类。

这个例子:当你实际使用的对象之外的方法,我将与结构的版本去,因为它使

class SomeNameChoosenByCompiler 
    { 
     public string Property1 {get; set; } 

     public string Property2 {get; set; } 
    } 

 new { Property1 = "something", Propert2 = "somethingElse" } 

编译器将产生类似代码更易读,易于理解,并且可以及时扩展。

此外,与dynamic你将失去​​编译时有利于

+0

但是,如何定义一个结构的文件大小需要更多的线我猜。 –

+3

这是不正确的。您正在考虑匿名类型。 – William

+0

是的,我知道匿名和动态是有区别的,但文件大小如何? –

0

你可以做到这一点无论哪种方式。

我个人的偏好是使用强类型结构,这样如果我在编译项目时会错误地输入任何属性名称。如果您使用expandoobject,则只有在代码运行时才会发现。

要考虑的另一件事是一个结构是value type而expandoobject显然是一个引用类型。这可能会影响您的决定,因为这两种类型可用于其余代码中。例如,值类型变量不能设置为空,并且它们遵循不同的复制语义。

0

结构类型的变量本质上是一组变量与胶带粘在一起。结构类型的堆对象(即,“盒装”结构实例)由运行时处理,就好像它是具有该结构类型的变量作为其唯一字段的类对象一样;任何在整个结构上运行的方法都是在该领域运行,而那些在结构领域运行的方法运行在其子域上。

如果将变量作为一个组使用,将变量组与变量绑定在一起的功能非常有用;但是,几乎所有人想要这样做的情况下,都需要至少在两个地方使用该结构(例如,从其复制的地方复制到的地方),但有些情况下所有地方都可能仅限于一个函数(例如,可能有一个变量prevStatecurrentState,每个变量都包含几个字段,并且可能希望能够拍摄currentState中的所有变量的快照,然后将所有变量恢复为其较早的值) 。结构可以很好的。

我建议通常有很好的结构定义。如果一个具有通过一个列表读取并计算最大值和最小值根据一些传入的IComparer<T>,具有如下结构的方法:

struct MinMaxResult<T> { public T Minimum, Maximum; } 

可以使比具有其封装了一个更复杂的数据类型的东西更清楚它的在性能领域,并试图执行不变量如Maximim >= Minimum等事实MinMaxResult是暴露字段的结构清楚地表明,给出的申报MinMaxResult mmr;,代码不应该期望mmr.Minimum有超越“写入最后的价值任何意义如果没有任何东西被写入,则为mmr.Minimumdefault(T)。“所有感兴趣的内容都会写入mmr;的MinMaxResult<T>更简明的定义,少它会分散从什么实际事情。

相关问题