2016-06-13 78 views
0

我有一个对象列表(它们的类型未提前未知)。下面的例子显示了硬编码值,但是我的实际代码通过从CSV文件中读取来填充参数列表。然后我想将这个参数列表传递给请求某些参数的典型方法。所以我将元素转换为所需的类型,如图所示。我得到错误:将一个对象变量传递给方法 - 指定的转换无效

Specified cast is not valid

当在运行时调用该方法。我应该如何去做到这一点?

var args = new List<object>(); 
     args.Add(5495); 
     args.Add("String1"); 
     args.Add(10133); 
     args.Add("String2"); 

     result = request.GetCustomer((long) args[0], (string) args[1], (int) args[2], (string) args[3]); 
+1

该错误明确告诉你为什么你不能执行转换,包括对象的实际类型以及要转换的对象。如果您希望在运行时不失败,您需要将对象转换为* actual *类型。 – Servy

+0

好吧,一个好的开始将是围绕这个和一个计数的try catch块,以便您可以看到csv中的哪一行是罪魁祸首。 – Kell

+0

@Kell一个'try' /'catch'块只会掩盖问题。他已经可以看到这个错误,他只需要修正他的代码中的错误。 – Servy

回答

4

当您添加值类型List<object>()

args.Add(5495); 

,该项目将Boxed。上面的行导致5495int被装箱。要开箱,您需要明确地将args[0]转换为其类型为 - (int)args[0]。因此,如果您的方法接受long作为其第一个参数,请执行(long)(int)args[0]。您拆箱args[0],然后将值转换为long

+1

中找到一些额外的信息,谢谢你!这解决了这个问题,我实际上意识到我可以只将该参数强制转换为(int)而不是(long)。 – AngieM

1

问题是5495将有一个int类型,并且您试图将其强制转换为long。你可以通过几种方式来解决这个问题,下面是其中之一。

替换此;

(long) args[0] 

与此;

(long) (int) args[0] 

这不会是一个非常有用的解决方案然而,因为你永远无法真正通过你的方法很值,而不是你能做到这一点;

args.Add((long) 5495); 
0

尝试使用转换。一changeType

 var args = new List<object>(); 
     args.Add(5495); 
     args.Add("String1"); 
     args.Add(10133); 
     args.Add("String2"); 


     long aLong = (long)Convert.ChangeType(args[0], typeof(long), CultureInfo.InvariantCulture); 

     string aStr = (string)Convert.ChangeType(args[1], typeof(string), CultureInfo.InvariantCulture); 

     int aInt = (int)Convert.ChangeType(args[2], typeof(int), CultureInfo.InvariantCulture); 
0

创建商店列表数据

类测试{

私人长期变量1 {获得单独的类;集;}

私人字符串变量2 {获取;集;}

private long Variable3 {get; set;}

私人字符串Variable4 {获取;集;}

}

变参=新名单();

VAR OBJ =新测试{

变量1 = 5495,

变量2 = “String1中”,

Variable3 = 10133,

Variable4 = “String2的”

}

args.add(obj);

result = request.GetCustomer(args [0] .Variable1,args [0] .Variable2,args [0] .Variable3,args [0] .Variable4);

0

让我们简化一下这个问题。

var args = new List<object>(); 
args.Add(5495); 
var l = (long)args[0]; // throws an exception 

args [0]里面究竟是什么?一个int(因为5495是编译器的一个int,如果你希望它是一个很长的类型5495L)。更确切地说,一个盒装int,因为你必须将其存储在参考类型的存储位置。盒装结构只能拆箱到相同的结构或可结构为空的结构。在我们的情况下,

var i = (int)args[0]; 
var nullable = (Nullable<int>)args[0]; 
var nullable1 == (int?)args[0]; 

都会正常工作。

虽然已将其拆箱,但您可以将其值转换为任何兼容的值。

您可以在msdn上阅读更多关于拳击和拆箱的信息。如果你想高效地使用C#,这是非常宝贵的理解。

你的问题的根本原因是你使用List<object>虽然,使拳击不可避免的。这是非常罕见的,你真的需要这样做,你应该认为你的架构可以避免它。

+0

感谢您关于拳击/拆箱(尤其是表演)的推荐阅读。我是一个小菜鸟。是的,这个设计可能并不理想。我必须为每个参数调用20-30个参数的不同方法,所以我厌倦了为每种方法定义20-30个变量 - >对象列表。如果你对我的情况有更好的建议,我会全力以赴。谢谢! – AngieM

+0

20-30参数*很多*。任何理智的方法都不应该有那么多。您应该重构大部分那些在您的业务逻辑中有意义的自定义类,并将这些对象的几个传递给您的方法。 – Falanwe

+0

这些主要是创建特定类型数据的Web服务方法(例如公司拥有大量关于公司的数据的公司记录)。是的,当我走时,我可能会重构一些常见的领域。 – AngieM