刚刚在这里找到了一些代码来编写访问某些数据库实体的代码......
public static OurCustomObject GetOurCustomObject(int primaryKey)
{
return GetOurCustomObject<int>(primaryKey, "usp_GetOurCustomObjectByID");
}
public static OurCustomObject GetOurCustomObject(Guid uniqueIdent)
{
return GetOurCustomObject<Guid>(uniqueIdent, "usp_GetOurCustomObjectByGUID");
}
private static OurCustomObject<T>(T identifier, string sproc)
{
if((T != typeof(int)) && (T == typeof(Guid)))
{
throw new ArgumentException("Identifier must be a string or an int");
}
//ADO.NET Code to make DB Call with supplied sproc.
}
Theres就是它的一些东西似乎不是generic
。这个事实
sprocs传入内部方法感觉很难看。但我能看到的唯一方法就是在
if(type == int)
sproc = "GetByID";
else if (type == Guid)
sproc = "GetByGUID";
同样抛出的异常看起来也很丑......无论如何都要使用where T:clause
e.g。
private static OurCustomObject<T>(T identifier) where T : int OR Guid
有关如何清理这一点的任何建议。
答案 0 :(得分:8)
你不能指定一个约束,上面写着“它是这两个中的一个”,没有。
您可以做的是:
Dictionary<Type, string> StoredProcedureByType = new Dictionary<Type, string>
{
{ typeof(Guid), "GetByGUID" },
{ typeof(int), "GetByID" }
};
然后使用:
string sproc;
if (!StoredProcedureByType.TryGetValue(typeof(T), out sproc))
{
throw new ArgumentException("Invalid type: " + typeof(T).Name);
}
这对于几种类型来说可能有点过头了,但如果涉及很多类型,它可以很好地扩展。
鉴于这两种类型都是值类型,您可以使用以下约束使其成为位更强大:
where T : struct
但仍然允许byte
等。
答案 1 :(得分:2)
您提供的代码看起来相当不错,因为private static OurCustomObject<T>(T identifier, string sproc)
是私有的。我甚至会从这个方法中删除异常检查,因为再次 - 它是私有的,所以这个类控制传递给方法的内容。 if语句会相当可怕并且过度设计。
答案 2 :(得分:1)
最重要的事情可能就是做这样的事情:
public interface IPrimaryKey
{
}
public class PrimaryGuidKey(Guid key) : IPrimaryKey
public class PrimaryIntegerKey(int key) : IPrimaryKey
private static OurCustomObject<T>(T identifier) where T : IPrimaryKey
答案 3 :(得分:0)
不支持这样的where子句以这种方式限制类型参数(不幸的是)。
在这种情况下,您可能会发现将identifier
作为对象传递,而使用泛型传递而不是实际上更清晰(当我需要类似的东西时,这就是我最终做的事情:似乎是最差的方法)。
这是一个C#弱的领域,既不是动态语言,也不能专门化模板(像C ++一样,只提供T = int和T = Guid的实现)。
Adendum:在这种情况下,我可能会坚持使用重载,但是将类型检查更改为Assert
,因为这是一种私有帮助方法。