简体   繁体   English

我应该为一个函数唯一的目的定义一个结构吗?

[英]Should i define a struct for the sole purpose of one function?

I got a function that is in need of a custom data type, one way to approach this problem is by defining a struct however this is only for just one function, wouldn't it be better if i just use a dynamic object instead? 我有一个需要自定义数据类型的函数,解决这个问题的一种方法是通过定义一个结构但是这只是一个函数,如果我只使用动态对象不是更好吗?

For example: 例如:

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

Or 要么

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

Note: 注意:

  1. While i can define all possible props in the struct, i don't know how many i need to use. 虽然我可以在结构中定义所有可能的道具,但我不知道我需要使用多少道具。

  2. The Example is not real it just shows the 2 possible approaches. 示例并不真实,它只显示了两种可能的方法。

That is not the purpose of dynamic . 这不是dynamic的目的。 Dynamic is used when you don't know the type until runtime (and have a good reason to have such a scenario). 如果在运行时之前不知道类型,则使用Dynamic(并且有充分的理由拥有这样的场景)。 Usages outside of this just de-value the strongly typed nature of C#, allowing code to compile that could be invalid at runtime. 除此之外的用法只是降低了C#的强类型性质,允许编译在运行时可能无效的代码。

If you need object A with properties B, C, D, then create that object, even if you are going to use it once. 如果需要具有属性B,C,D的对象A,则创建该对象,即使您打算使用它一次。 Besides, you will need to use that object when something calls your function and needs to access the properties of the returned object. 此外,当某些东西调用您的函数并需要访问返回对象的属性时,您将需要使用该对象。 It's better that those properties are known and strongly typed. 这些属性最好是已知且强类型的。 You can use a struct instead of a class if you prefer, but make it a strongly typed object. 如果您愿意,可以使用结构而不是类,但将其设置为强类型对象。

Edit: The original question was edited to indicate that the function does not return the object. 编辑:编辑原始问题以指示该函数不返回该对象。 Nonetheless, the above still otherwise holds true - that is, this is not a scenario when you don't know the type until runtime, and therefore it is not the right scenario to use dynamic . 尽管如此,上述情况仍然适用 - 也就是说,这不是直到运行时才知道类型的情况,因此使用dynamic 不是正确的方案。 Since the usage of the object is short-lived, I would use a struct . 由于对象的使用是短暂的,我会使用struct See here for in-depth discussion on when struct should be used: When to use struct? 看到这里进行深入讨论时, struct应使用: 当使用结构?

There is no performance impact if you choose any of the two solutions you came up with. 如果您选择您提出的两种解决方案中的任何一种,则不会对性能产生任何影响。

When the compiler meets the dynamic keyword it will do the same, will define a class that contains all the members defined. 当编译器遇到dynamic关键字时,它将执行相同的操作,将定义一个包含所有已定义成员的类。

for this example: 对于这个例子:

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

compiler will generate something like: 编译器将生成如下内容:

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

        public string Property2 {get; set; } 
   }

as you are actually using the object outside of your method i would go with the struct version as it makes the code more readable and easy to understand and maybe scalable in time. 因为你实际上在你的方法之外使用对象,我会使用struct版本,因为它使代码更易读,易于理解,并且可以及时扩展。

Also, with dynamic you would loose compile-time benefits 此外,使用dynamic您将失去编译时的好处

You can do it either way. 你可以这样做。

My personal preference would be to use the strongly typed struct so that if I mistype any of the property names I'll find out when I compile the project. 我个人的偏好是使用强类型结构,这样如果我输入错误的任何属性名称,我将在编译项目时找到它。 If you use the expandoobject you won't find out until the code runs. 如果您使用expandoobject,则在代码运行之前您将无法找到。

The other thing to consider is that a struct is a value type while an expandoobject is obviously a reference type. 另一件需要考虑的是struct是一个值类型,而expandoobject显然是一个引用类型。 This may affect your decision because of the way the two types can be used in the rest of your code. 这可能会影响您的决定,因为这两种类型可以在其余代码中使用。 For example, a value type variable cannot be set to null, and they follow different copying semantics. 例如,值类型变量不能设置为null,并且它们遵循不同的复制语义。

A variable of a structure type is, in essence, a group of variables stuck together with duct tape. 结构类型的变量实质上是与管道胶带粘在一起的一组变量。 A heap object of a structure type (ie a "boxed" struct instance) is processed by the runtime as though it were a class object with a variable of that structure type as its only field; 结构类型的堆对象(即“盒装”结构实例)由运行时处理,就好像它是一个类对象,该结构类型的变量作为其唯一的字段; any methods which would operate on the structure as a whole operate on that field, while those which would operate on the fields of the structure operate on its sub-fields. 任何在整个结构上运行的方法都在该领域运作,而在结构领域运作的方法则在其子领域运作。

The ability to binding groups of variables together with duct tape is useful if one will be using the variables as a group; 如果将变量用作组,则将变量组与管道磁带绑定在一起的能力非常有用; almost all cases where one would want to do that, however, would require that the structure be used in at least two places (eg a place it's copied from, and a place it's copied to), though there are cases where all the places might be confined to a single function (eg one may have a variables prevState and currentState , each containing a few fields, and may want to be able to take a snapshot of all the variables in currentState and later revert all the variables to their earlier values). 然而,几乎所有想要这样做的情况都要求结构至少在两个地方使用(例如,它被复制的地方,以及它被复制到的地方),尽管有些情况下所有地方都可能被限制在单个函数中(例如,一个函数可能有变量prevStatecurrentState ,每个变量包含几个字段,并且可能希望能够获取currentState中所有变量的快照,然后将所有变量恢复为其先前的值) 。 Structures can be good for that. 结构可能对此有利。

I would suggest that it's often good to have very bare-bones structure definitions. 我建议有一个非常简单的结构定义通常是好的。 If one has a method which reads through a list and computes the minimum and maximum values according to some passed-in IComparer<T> , having a structure: 如果有一个方法可以读取列表并根据一些传入的IComparer<T>计算最小值和最大值,则具有以下结构:

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

could make things clearer than having a more complicated data type which wraps its fields in properties and tries to enforce invariants such as Maximim >= Minimum , etc. The fact that MinMaxResult is a structure with exposed fields makes it clear that given the declaration MinMaxResult mmr; 可以使事情比使用更复杂的数据类型更清楚,数据类型将其字段包装在属性中并尝试强制执行不变量,例如Maximim >= MinimumMinMaxResult是具有暴露字段的结构的事实清楚地表明给定声明MinMaxResult mmr; , code shouldn't expect mmr.Minimum to have any meaning beyond "the last value written to mmr.Minimum , or default(T) if nothing was written." ,代码不应该指望mmr.Minimum具有超出“写入mmr.Minimum的最后一个值,或者如果没有写入任何内容则default(T) ”之外的任何含义。 Everything of interest is going to be in whatever writes to mmr ; 感兴趣的一切都将出现在对mmr任何写作中; the more concise definition of MinMaxResult<T> , the less it will distract from what's actually going on. MinMaxResult<T>定义越简洁,它就越不会分散实际发生的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM