2012-03-13 52 views
1

假设我有以下类:指定泛型类型中使用领域

public class MyClass 
{ 
    public decimal myDecimal; 
    public string myString; 
} 

我想用DataRowExtensions方法Field<>

目前,我使用的是类,像这样:

MyClass myClass = new MyClass(); 
myClass.myDecimal = row.Field<decimal>("MyDecimalColumnName"); 
myClass.myString = row.Field<string>("MyStringColumnName"); 

但是,如果我决定将myDecimal的类型更改为decimal以外的其他类型,我想要调用row.Field以反映正确的数据。

我想类似的语法如下东西:

myClass.myDecimal = row.Field<typeof(myClass.myDecimal)>("MyDecimalColumnName"); 

这并不编译,我不知道如何使用typeofGetType()刚刚返回decimal,无论将被调用。

有没有办法做到这一点,或类似的东西?我认为这可以在编译时完成,因为类型是已知的,因为泛型是编译时构造。

谢谢!

+0

看看[这里](http://stackoverflow.com/q/196936/754438) – Reniuz 2012-03-13 14:32:04

+0

不能编译*推断*该类型的参数? – davisoa 2012-03-13 14:32:19

+2

@davisoa不用于* return *值,不是 – 2012-03-13 14:32:42

回答

5

首先,请注意,公共领域通常是一个非常糟糕的主意;但如果我们假设这是一个私人支持领域,这里有两个有趣的选择;

首先是利用泛型类型推断;这并不为返回类型的工作,但确实的参数,所以你可以有:

row.GetField("MyDecimalColumnName", out obj.someField); 

这里说的:

GetField<T>(string name, out T value); 

另一个技巧是使用隐含的运营商,即有GetField(string)返回一个虚拟对象,它具有隐式转换运算符到几种类型,如int,decimal等,并在运算符中进行工作/转换。有点哈克,但会工作 - 语法为:

myClass.myDecimal = row.Field("SomeColumn") 

有:

SomeDummyType GetField(string name); 

,并有一个隐含的静态转换运算符或几个SomeDummyType

但是! IMO best这里的选项是使用诸如ORM或micro-ORM之类的工具为您加载值,并且完全不使用DataRow

另一种简单的选择就是去旧学校:

myClass.myDecimal = (decimal)row["SomeColumn"]; 

我的意思是 - 是.Field<T>真正帮助你所有的东西?你是否真的经常重构你的课程,这是值得担心的吗?

+0

我喜欢你的'row.GetField'建议,但我想知道为什么我不能明确地设置返回值的类型。至于使用'Field ',我使用它,因为它有助于使用可空类型(DataRow为可空列返回'DBNull.Value',为不可列的列返回'null')。例如'小数?如果MyColumn为空,x =(decimal?)row [“MyColumn”]'将失败,但如果MyColumn不存在则不会失败。 – Matthew 2012-03-13 14:43:55

+1

@Matthew是的,不要让我开始疯狂;我不是'DBNull.Value'的粉丝 – 2012-03-13 14:46:22

+0

我想我会和你的'row.GetField'例子一起去,谢谢! – Matthew 2012-03-13 14:47:26

1

您可以使用反射动态构造适当的泛型方法:

MyClass myClass = new MyClass(); 
var myType = typeof(MyClass.myDecimal); 
var myMethod = Type.GetType("System.Data.DataRowExtensions") 
    .GetMethod("Field", new[]{typeof(DataRow), typeof(string)); 
var genericMethod = myMethod.MakeGenericMethod(new[]{myType}); 

myClass.myDecimal = genericMethod.Invoke(row, new object[]{"MyDecimalColumnName"}); 
+0

我可能会在此上面显示_could_。是的,但它绝对不是最佳解决方案。 – 2012-03-13 14:37:20