2010-09-09 112 views
4

我知道这可能是一个非常简单的问题,但我现在有一个大脑放屁。我正在尝试创建一个可以采用2种自定义类型之一的方法。基本上这个方法的主体对于两个类型都是相同的,因为它们都有一个Name属性(我正在比较Name属性以用于排序)。我应该怎么做?如何使一种方法采取2种不同的类型

我首先想到的是刚刚与两种类型作为参数重载方法:

int Compare(Type1 first, Type1 second) 
int Compare (Type2 first, Type2 second) 

,但这些方法的身体结束了相同因而它似乎是一个浪费。

我的下一个想法是使用泛型,但这似乎并不正确,因为我没有真正使其通用,因为它只能与2种特定类型一起使用。

说明:“自定义”类型实际上不是我的自定义类型。我的意思是他们不是内置类型。我无法控制这些类型或继承层次结构中的内容。他们只是碰巧拥有Name属性。

回答

7

如果两种类型派生自相同的基础或使用相同的接口,并且没有其他类使用基础和/或接口,则泛型仍然是一个选项。

int Compare<T>(T first, T second) where T : IHasName 

简而言之,有两个重载是要走的路。

注意:如果你有.NET 4,你可以使它成为一个运行时的东西,并使该方法动态。

int Compare(dynamic first, dynamic second) 

在这种情况下,任何你扔它会编译,但它会在运行时炸毁如果Name属性不存在。个人而言,如果我不能修改类型以使用通用接口,那么我会去重载并获得编译时安全。

+2

使这两种类型实现一个共同的界面看起来像去恕我直言的方式。 – 2010-09-09 20:57:01

+0

两者都不可能。它们不是从相同的基类派生的,这两种类型不是由我写的,所以我不能改变它。 – KrisTrip 2010-09-09 20:57:55

+0

即使类型不是由你写的,你仍然可以采取超载路线? – Bertvan 2010-09-09 20:59:30

1

如果它可以只有与2种类型一起使用,然后使2重载。

+0

我确实最终走了这条路线,所以+1对你来说,但我用更多的选项标记了答案,正如其他选项可能会帮助其他人在未来更多。 – KrisTrip 2010-09-09 21:36:55

0

也许不是最好的解决办法,但是这是我脑海: 你让一个方法,如:

int MainCompare(Type1 first1, Type1 second1, Type2 first2, Type2 second2, bool firsttype){...} 

然后你就可以可以有两种方法比较具有一行。

int compare(Type1 first, Type1 second){ 
    return MainCompare(first, second, null, null, true); 
} 


int compare(Type2 first, Type2 second){ 
    return MainCompare(null, null, first, second, false); 
} 

你的MainCompare只会根据它使用的类型而改变一点。

1

重载该方法将是一种很好的方法,使它只有两种特定的类型。为避免重复代码,您可以在场景后面使用泛型:

public int Compare(Type1 first, Type1 second) { 
    return Compare<Type1>(first, second); 
} 

public int Compare(Type2 first, Type2 second) { 
    return Compare<Type2>(first, second); 
} 

private int Compare<T>(T first, T second) { 
    ... 
} 
+1

您仍然需要将'T'限制为基本接口/类以便能够调用其上的特定方法... – porges 2010-09-09 21:19:54

4

好的,我在第一个答案中完全读错了你的问题。这是一个更好的:)

过载是你最好的选择。由于比较的结果只取决于Name,作出这样做比较的方法,然后调用它:

private int Compare(string first, string second) 
{ 
    // do comparison 
} 

public int Compare(Type1 first, Type1 second) 
{ 
    return Compare(first.Name, second.Name): 
} 

public int Compare(Type2 first, Type2 second) 
{ 
    return Compare(first.Name, second.Name); 
} 

编辑:

既然你有一个以上的项目,有两件事情可以做:

public int Compare(string first1, string second1, X first2, X second2 ... 

但是这会变得有点难看。另一种方法是提供一个投影提取值:

private int Compare<T>(T first, T second, Func<T,Tuple<string,int,TypeX,TypeY>> projection) 
{ 
    // test for first==null, second==null, etc... 

    var nicerFirst = projection(first); 
    var nicerSecond = projection(second); 

    // compare objects using nicerFirst.Item1, nicerFirst.Item2, etc. 
} 

那么你比较看起来类似:

int Compare(Type1 first, Type1 second) 
{ 
    return Compare(first, second, x => Tuple.Create(x.Name, x.Int, x.X, x.Y)); 
} 
+0

实际上,除了名称之外,我还做了其他比较,所以这不太合适。尽管如此+1,谢谢! – KrisTrip 2010-09-09 21:38:19

+0

我会扩大我的答案:) – porges 2010-09-09 21:47:51

0

这可能是一个过分的解决方案,但你可以使适配器的两个班,并让他们实现一个共同的接口:

public class MyType1 : ICommonInterface, Type1 
{ 
    // Where you can define 'Somethin' in the common interface 
    public string Something 
    { 
     get { return base.Something; } 
     set { base.Something = value; } 
    } 

    /* ... */ 
} 

public class MyType2 : ICommonInterface, Type2 
{ 
    // If there is no base.Something on Type2, you can re-name it assuming 
    // its intent is the same as Something 
    public string Something 
    { 
     get { return base.SomethingElse; } 
     set { set base.SomethingElse = value; } 
    }   
} 

然后你就可以实现基本上什么@Anthony Pegram(+1)有:

int Compare<T> (T first, T second) where T : ICommonInterface 
{ 
    return first.Something.CompareTo(second.Something); 
} 
8

到目前为止已经够奇怪了没有人发布我认为是最明显的选择:以名称作为比较参数。使调用者从对象中获取名称属性。如果所有的方法需要使用的名称,那么为什么你传递的对象的其余部分?

如果需要抽象过的“我能得到一个名字出了这种事”的概念,那么这样做:

例子:

int Compare(string name1, string name2) { ... whatever ... } 
int Compare<T>(T t1, T t2, Func<T, string> getName) 
{ 
    return Compare(getName(t1), getName(t2)); 
} 

现在你可以说:

Compare(car1, car2, c=>c.Name); 
Compare(employee1, employee2, e=>e.Name); 

等等。

+0

@Porges基本上发布了这个回复(或者非常相似)。实际上,除了名称之外,我还做了其他比较,所以这不起作用。 +1虽然简单。 – KrisTrip 2010-09-10 14:28:25

相关问题