我在源格式和目标格式之间有一个m到n的关联。 (现在,m = 2,n = 5,n增长快于m)。
我希望得到一个事件,输入格式为Item
或DbDataReader
,并将其转换为其他类型,它们将提供所需的构造函数:
public MyEvent(Item item)
public MyEvent(DbDataReader ddr)
public MyEventDetailed(Item item)
public MyEventDetailed(DbDataReader ddr)
public MyEventInfo(Item item)
public MyEventInfo(DbDataReader ddr)
public MyEventNotification(Item item)
public MyEventNotification(DbDataReader ddr)
public MyEventReminder(Item item)
public MyEventReminder(DbDataReader ddr)
每个构造函数将由两个DataStore中的一个使用:
EwsDataStore : DataStoreBase
DbDataStore : DataStoreBase
现在每个都实现了getEvent
:
DataStoreBase
方法
abstract MyEventDetailed getEvent(string uniqueId);
现在我也需要所有其他目标格式,所以我想让它们像这样通用:
abstract T getEvent<T>(string uniqueId) where T : IEvent, new()
可能的EwsDataStore实现
getEvent<T>(string uniqueId) where T : IEvent, new() // TODO: All affected models have to implement IEvent interface
{
Item item;
try {
item = Item.Bind(service, new ItemId(uniqueId));
} catch(Exception e) {
throw new ArgumentException("An item by that Id was not found in the data store", "uniqueId", e);
}
// return T.FromItem(item); // Needs static IEvent.FromItem method.
return new T(item); // IEvent has to enforce constructor with parameter Item on all implementing classes
}
和Sql:
getEvent<T>(string uniqueId) where T:IEvent, new() // TODO: All affected models have to implement IEvent interface
{
SQL db = new SQL();
db.AddParameter("@uniqueId", uniqueId)
SqlDataReader sdr = db.ExecuteReader("SELECT * FROM datastore WHERE uniqueId = @uniqueId");
if(!sdr.HasRows) throw new ArgumentException("An item by that Id was not found in the data store");
sdr.Read();
// return T.FromDdr(sdr); // Needs static IEvent.FromDdr method.
return new T(sdr); // IEvent has to enforce constructor with parameter DataReader on all implementing classes
}
但是在泛型类型上都不允许使用带参数的构造函数或静态方法,每个都抛出以下两个错误消息之一:
修饰符'static'对此项目无效
'T':创建变量类型的实例时无法提供参数
搜索这些错误消息;我发现"the instance method can simply (sic!) delegate to a static method",或者我可以使用Reflection
或Activator
。
它们似乎都不够容易/直接地编写,理解,使用和维护。
是否有一种简单的方法可以使用继承和泛型来创建基于我提供的类型的所有不同类型,即使他们不熟练深入C#继承,其他程序员也可以理解/遵循这些类型?
答案 0 :(得分:1)
首先,我认为你误解了new
约束。 new
表示泛型类型T
具有无参数构造函数new T()
,它似乎与您想要的相反。
只需删除new
约束,然后使用T
类创建Activator
的实例:Activator.CreateInstance
:
return (T)Activator.CreateInstance(typeof(T), item);
另外,请注意您不能在界面中定义静态成员,也不能继承它们。因此,语言中无法对允许您调用T
的泛型T.MyStaticMethod()
表达约束。