具有多个类的通用

我正在尝试创建这种通用方法来简化操作,但我想我搞砸了! 你能解决我的问题吗?

这编译:

private string ConcatenateText(MyEntity myEntity) where T1 : Supplier, new() where T1 : Employee, new() where T2 : SupplierDepartment, new() where T2 : EmployeeDepartment, new() { T1 p = new T1(); T2 r = new T2(); //Code here for myEntity treatment return mystring; } 

虽然这不编译:

 protected void mybutton1_Click(object sender, EventArgs e) { string mystring = ConcatenaText(myEntity); } //This does not compile protected void mybutton2_Click(object sender, EventArgs e) { string mystring = ConcatenaText(myEntity); } 

消息:类型Supplier不能用作generics类型或方法ConcatenateText(MyEntity myEntity)中的类型参数T1。 从供应商到员工没有隐式参考转换

可以这样做吗? 我究竟做错了什么? 可以改进吗?

编辑:

而MyEntity只是另一个类,以便在这个generics方法中处理它! 它与类型T无关。它只是一个论点。 但很明显,我不能这样做,使用这样的2种类型。 我认为我可以分配一个或另一个,CLR独立于我的初始化可以按我的意愿做出反应。 我会接受那些分享更多信息的答案。

首先,尝试在generics参数T1上设置两个类型约束的代码无法编译

 where T1 : Supplier, new() where T1 : Employee, new() 

出现以下错误:

已经为类型参数’T1’指定了约束子句。 必须在单个where子句中指定类型参数的所有约束。

正如MSDN文章所述,您只能对每个通用参数使用一个约束(请参阅http://msdn.microsoft.com/en-us/library/bb384067.aspx )。

“对于多个类型参数,请为每个类型参数使用一个where子句……”

您也不能将多个类名放入一个’where’约束中。 只有一个类名和几个接口。

 where T1 : Supplier, IContractor, IComparable, new() 

请记住,此约束规定您作为通用参数T1提供的实际类型必须是Supplier类或Supplier类本身的后继,并且它必须实现IContractorIComparable接口。

只要您的方法接受MyEntity对象并且您没有指定它与Employee和Supplier类之间的关系,我就无法猜测此MyEntity类如何了解Employee和Supplier类以及此关系如何帮助您。

我唯一能建议的是创建一个接口或基类,并从中inheritance你的两个类。 这是我看到创建generics方法的唯一好理由。 它可能看起来像这样:

 class Program { static void Main(string[] args) { Method1(); Method1(); } private static void Method1() where T1 : IContractor, new() { } } public class Supplier : IContractor { string IContractor.Name { get{return "Supplier-Mufflier";} } } public class Employee : IContractor { string IContractor.Name { get{return "Employee-Merloyee";} } } public interface IContractor { string Name { get; } } 

如果您的类Supplier和Employee没有共同的重要内容,足以创建一个他们可以实现的通用接口,那么您就不应该使用通用方法来处理它们。

为每种类型创建重载方法。

想象一下,你有两个class: WifeWine 。 两者都具有Age和同一类型的属性。 但是,甚至不要考虑为这些类创建一个公共接口IAged 。 阶级的本质和Age的意义是如此不同,以至于不应该统一它们。 然而,一些常见的逻辑可能完全为您服务 例如:

 private double AgeQualify(Wife someWife) { return 1 / (someWife.Age * someWife.Beachness); } private double AgeQualify(Wine someWine) { return someWine.Age / someWine.Sugar; } 

您需要制作单独的版本:

 private string ConcatenateText(MyEntity myEntity) where T1 : Supplier, new() where T2 : SupplierDepartment, new() { T1 p = new T1(); T2 r = new T2(); return mystring; } private string ConcatenateText(MyEntity myEntity) where T1 : Employee, new() where T2 : EmployeeDepartment, new() { T1 p = new T1(); T2 r = new T2(); return mystring; } 

或者需要让它们共享一个基类:

 private string ConcatenateText(MyEntity myEntity) where T1 : EmployeeSuplierBase, new() where T2 : EmployeeSupplierDeparmentBase, new() { T1 p = new T1(); T2 r = new T2(); return mystring; } 

我更喜欢单独的版本,因为有了他们,他们不能用SupplierEmployeeDeparment调用它(反之亦然)

在这种情况下你真的不应该使用generics。 只有两个选择。

所以:

 string ConcatenateText(Supplier Entity) { ...code...} string ConcatenateText(Employee Entity) { ...code...} 

你可以做的是将基础类集中在所有常用方法中。

比如说,如果供应商和员工都有Name

 class BaseClass { public string Name {get; set;} } class Employee : BaseClass { //emplyee stuff except name and other things already in base } class Supplier : BaseClass { //supplier stuff except name and other things already in base } 

然后,该方法采用BaseClass

 private string ConcatenateText(BaseClass Entity) { //code }