Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何删除C#中的强类型?_C# - Fatal编程技术网

如何删除C#中的强类型?

如何删除C#中的强类型?,c#,C#,假设我必须将从数据库读取的内容转换为对象。我可能有这样的想法: public class Foo { int a; DateTime b; float c; public Foo(int a, DateTime b, float c) { this.a = a; this.b = b; this.c = c; } internal Foo(DataRow dr) { this.a

假设我必须将从数据库读取的内容转换为对象。我可能有这样的想法:

public class Foo {

    int a;
    DateTime b;
    float c;

    public Foo(int a, DateTime b, float c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    internal Foo(DataRow dr) {
        this.a = (int) dr["a"];
        this.b = (DateTime) dr["b"];
        this.c = (float) dr["c"];
    }

}
您是否可以使用
dynamic
关键字来删除类型检查并自动强制转换?理想情况下,它只适用于
内部
构造函数。

您的意思是这样吗

public class Foo {
    dynamic a;
    dynamic b;
    dynamic c;

    public Foo(int a, DateTime b, float c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }
    internal Foo(DataRow dr) {
        this.a = dr["a"];
        this.b = dr["b"];
        this.c = dr["c"];
    }
}
当然,如果你真的那么讨厌铸造,那么你可以这样做,然后编译器不再是你最好的朋友,以防止你射中自己的脚

如果您主要关心的是摆脱丑陋的强制转换,那么另一种选择是使用方法扩展

提供对指定行中每个列值的强类型访问

用法示例:

public class Foo {
    int a;
    DateTime b;
    float c;

    public Foo(int a, DateTime b, float c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }
    internal Foo(DataRow dr) {
        this.a = dr.Field<int>("a");
        this.b = dr.Field<DateTime>("b");
        this.c = dr.Field<float>("c");
    }
}
公共类Foo{
INTA;
日期时间b;
浮点数c;
公共Foo(int a、DateTime b、float c){
这个a=a;
这个.b=b;
这个.c=c;
}
内部Foo(数据行dr){
此.a=dr.Field(“a”);
此.b=dr.Field(“b”);
此.c=dr.Field(“c”);
}
}
你是说像这样

public class Foo {
    dynamic a;
    dynamic b;
    dynamic c;

    public Foo(int a, DateTime b, float c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }
    internal Foo(DataRow dr) {
        this.a = dr["a"];
        this.b = dr["b"];
        this.c = dr["c"];
    }
}
当然,如果你真的那么讨厌铸造,那么你可以这样做,然后编译器不再是你最好的朋友,以防止你射中自己的脚

如果您主要关心的是摆脱丑陋的强制转换,那么另一种选择是使用方法扩展

提供对指定行中每个列值的强类型访问

用法示例:

public class Foo {
    int a;
    DateTime b;
    float c;

    public Foo(int a, DateTime b, float c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }
    internal Foo(DataRow dr) {
        this.a = dr.Field<int>("a");
        this.b = dr.Field<DateTime>("b");
        this.c = dr.Field<float>("c");
    }
}
公共类Foo{
INTA;
日期时间b;
浮点数c;
公共Foo(int a、DateTime b、float c){
这个a=a;
这个.b=b;
这个.c=c;
}
内部Foo(数据行dr){
此.a=dr.Field(“a”);
此.b=dr.Field(“b”);
此.c=dr.Field(“c”);
}
}

您可以在
数据行周围实现一个动态包装器(警告:未测试的代码)

然后按如下方式修改内部构造函数:

internal Foo(DynamicDataRow ddr) {
    dynamic dr = ddr;
    this.a = dr.a;
    this.b = dr.b;
    this.c = dr.c;
}
并称之为

var foo = new Foo(new DynamicDataRow(someDataRowObject));

与sstan的答案不同,您将失去编译时类型检查的所有好处。这听起来很糟糕,但实际上并没有那么糟糕,因为即使使用
DataRowExtensions.Field
extension方法,类型检查仍然在运行时进行,因为编译器无法检查数据库中列的数据类型是否与您试图将该信息填充到的字段匹配。因此,无论哪种方式都将进行运行时类型检查。

您可以在
数据行周围实现一个动态包装器(警告:未测试的代码)

然后按如下方式修改内部构造函数:

internal Foo(DynamicDataRow ddr) {
    dynamic dr = ddr;
    this.a = dr.a;
    this.b = dr.b;
    this.c = dr.c;
}
并称之为

var foo = new Foo(new DynamicDataRow(someDataRowObject));


与sstan的答案不同,您将失去编译时类型检查的所有好处。这听起来很糟糕,但实际上并没有那么糟糕,因为即使使用
DataRowExtensions.Field
extension方法,类型检查仍然在运行时进行,因为编译器无法检查数据库中列的数据类型是否与您试图将该信息填充到的字段匹配。因此,无论哪种方式,都将进行运行时类型检查。

听起来你想重新发明ORM。@zzzzBov是的,只使用ORM框架会很好,但我正在处理的系统没有使用ORM框架,所以这是我必须处理的。那么你想将DataRow转换为Foo吗?我已经很久没有在没有ORM的情况下工作了,但是那个内部构造函数工作了吗?除了@zzbov的反应,你可以检查一下:或者你到底想做什么?只是为了跳过转换,你可以使用简单的对象。听起来你想重新发明ORM。@ZZZBOV是的,只使用ORM框架会很好,但我正在使用的系统没有使用ORM框架,所以这就是我必须使用的。那么你想将DataRow转换为Foo?我已经很久没有在没有ORM的情况下工作了,但是那个内部构造函数工作了吗?除了@zzbov的反应,你可以检查一下:或者你到底想做什么?只需跳过强制转换,您就可以使用简单对象。除了提供与op稍有不同的语法外,它还会带来什么额外的好处吗?@Arghya:不太会。它只是消除了丑陋的强制转换,我认为这是困扰OP的原因。但它本质上也是如此,而且你同样容易受到
InvalidCastException
s的影响。第一个可以工作,但可能非常昂贵(大小和速度),你不再拥有(便宜的)POCO,你拥有动态魔法things@pm100:因此,还有很多其他的,我一点也不提倡这个选项。@sstan我的评论是为op设计的,除了提供与op几乎不同的语法外,它还会带来什么额外的好处吗?@Arghya:不太可能。它只是消除了丑陋的强制转换,我认为这是困扰OP的原因。但它本质上也是如此,而且你同样容易受到
InvalidCastException
s的影响。第一个可以工作,但可能非常昂贵(大小和速度),你不再拥有(便宜的)POCO,你拥有动态魔法things@pm100:因此,还有许多其他人,我根本不提倡这个选项。@sstan我的评论是针对有可能的
dynamic dr=new DynamicDataRow(row)
以便调用方可以一如既往地传递
数据行
。是的,如果它是现有/遗留代码,我会保持公共API不变,但如果它是新设计的,我会将API设置为采用实际使用的类型。但是
DynamicDataRow
只是一个转换助手,一个实现细节。没有理由将其作为接口的一部分公开
这样调用者就可以一如既往地传递
数据行了。是的,如果它是现有的/遗留的代码,我会保持公共API不变,但是如果它是新设计的,我会将API设置为采用实际使用的类型。但是
DynamicDataRow