具有多个类的通用
我正在尝试创建这种通用方法来简化操作,但我想我搞砸了! 你能解决我的问题吗?
这编译:
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类本身的后继,并且它必须实现IContractor
和IComparable
接口。
只要您的方法接受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: Wife
和Wine
。 两者都具有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; }
我更喜欢单独的版本,因为有了他们,他们不能用Supplier
和EmployeeDeparment
调用它(反之亦然)
在这种情况下你真的不应该使用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 }