如何使一个方法采用两种不同的类型
我知道这可能是一个非常简单的问题,但我现在脑子很乱。我正在尝试创建一种可以采用两种自定义类型之一的方法。基本上,这两种类型的方法主体都是相同的,因为它们都有一个 Name 属性(我正在对用于排序的 Name 属性进行比较)。我该怎么做?
我的第一个想法只是用两种类型作为参数来重载该方法:
int Compare(Type1 first, Type1 second)
int Compare (Type2 first, Type2 second)
但方法的主体最终是相同的,因此这似乎是一种浪费。
我的下一个想法是使用泛型,但这似乎不对,因为我并没有真正使其泛型,因为它只能与 2 种特定类型一起使用。
澄清:“自定义”类型实际上不是我的自定义类型。我的意思是它们不是内置类型。我无法控制这些类型或继承层次结构中的内容。它们只是碰巧都具有 Name 属性。
I know this is probably a really simple question but I'm having a brain fart at the moment. I am trying to create a method that can take one of 2 custom types. Basically the body of this method will be identical for both the types as they both have a Name property (I'm doing a comparison on the Name property to use in sorting). How should I do this?
My first thought was just to overload the method with the two types as arguments:
int Compare(Type1 first, Type1 second)
int Compare (Type2 first, Type2 second)
but the body of the methods ended up being identical thus it seems like a waste.
My next thought was to use generics but that doesn't seem right because I'm not really making it generic as it can only be used with 2 specific types.
Clarification: The "custom" types are actually not my custom types. What I meant was taht they are not built-in types. I do not have control over what is in these types or the inheritence hierarchy. They just both happen to have the Name property.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
奇怪的是,到目前为止,没有人发布在我看来是显而易见的选择:将名称作为比较的参数。让调用者从对象中获取 name 属性。如果所有方法需要使用的只是名称,那么为什么要传递对象的其余部分呢?
如果你需要抽象出“我可以从这个东西中得到一个名字”的概念,那么就这样做:
示例:
现在你可以说:
等等。
Oddly enough so far no one has posted what seems to me to be the obvious choice: take the name as the argument of the comparison. Make the caller get the name property out of the object. If all the method needs to use is the name then why are you passing in the rest of the object?
If you need to abstract over the notion of "I can get a name out of this thing" then do that:
Example:
And now you can say:
and so on.
如果两种类型派生自相同的基类或使用相同的接口,并且没有其他类使用该基类和/或接口,那么泛型仍然是一个选项。
除此之外,拥有两个重载就是正确的选择。
注意:如果您有 .NET 4,则可以将其设为运行时事物并使方法动态化。
在这种情况下,您向其抛出的任何内容都会编译,但如果
Name
属性不存在,它将在运行时崩溃。就我个人而言,如果我无法修改类型以使用通用接口,那么我会使用重载并获得编译时安全性。
Generic is still an option if the two types derive from the same base or use the same interface, and no other classes use the base and/or interface.
Short of that, having the two overloads is the way to go.
Note: If you have .NET 4, you could make it a runtime thing and make the method dynamic.
In which case anything you throw at it will compile, but it will blow up at runtime if the
Name
property is not present.Personally, if I can't modify the type to use a common interface, then I would go with the overloads and get compile-time safety.
好吧,我在第一个答案中完全错误地阅读了你的问题。这是一个更好的:)
重载是你最好的选择。由于比较结果仅取决于
Name
,因此创建一个执行该比较的方法,然后调用它:编辑:
由于您有多个项目,因此您可以做两件事do:
但这会变得有点难看。另一种方法是提供投影来提取值:
然后您的比较如下所示:
Okay, I read your question completely wrong in the first answer. Here's a better one :)
Overloads are your best bet. Since the comparison result only depends upon
Name
, make a method that does that comparison, then call it:Edit:
Since you have more than one item, there's two things you can do:
But that's going to get a bit ugly. An alternative is to provide a projection to extract the values:
Then your compare looks something like:
如果它只能与两种类型一起使用,则进行 2 个重载。
If it can only be used with 2 types, then make 2 overloads.
重载该方法是使其仅采用两种特定类型的好方法。为了避免重复代码,您可以在幕后使用泛型:
Overloading the method would be a good way to make it take only two specific types. To avoid repeating the code, you can use generics behind the scene:
也许不是最好的解决方案,但这就是我的想法:
您可以创建一个如下方法:
然后您可以用一行来拥有两个 Compare 方法。
你的 MainCompare 只会根据它使用的类型而改变一点。
Maybe not the best solution but this is what comes to my mind:
You make a method like:
Then you can can have the two Compare methods with one line.
your MainCompare will just change a bit depending on what type it's using.
这可能是一个过度的解决方案,但是您可以为这两个类制作适配器,并让它们实现一个通用接口:
然后您基本上可以完全实现 @Anthony Pegram (+1) 所拥有的内容:
This is probably an overboard solution, but you could make adapters for the two classes, and have them implement a common interface:
Then you can implement basically exactly what @Anthony Pegram (+1) had: