在静态类中返回多个值
Posted
技术标签:
【中文标题】在静态类中返回多个值【英文标题】:return multiple values in static class 【发布时间】:2012-07-24 23:50:34 【问题描述】:如何在以下类中返回 FirstName 和 Surname?
public static string GetAccount(int AccountId)
LinqSqlDataContext contextLoad = new LinqSqlDataContext();
var q = (from p in contextLoad.MyAccounts
where p.AccountId == AccountId
select new Name = p.FirstName, Surname = p.Surname ).Single();
return ??;
【问题讨论】:
假设您也希望返回类型正确,并且您不只是想要return string.Format("0 1",q.Name,q.Surname);
【参考方案1】:
您可以返回强类型类、动态对象或元组。 我更喜欢返回一个强类型的类。
使用dynamic
类型的问题是你没有得到
智能感知和异常仅在运行时。
元组的问题是它没有告诉你什么 你回来。您或其他开发人员必须阅读该方法 知道什么名字和什么姓氏。
样本
public class MyResult
public string Name get; set;
public string Surname get; set;
public static MyResult GetAccount(int AccountId)
LinqSqlDataContext contextLoad = new LinqSqlDataContext();
var q = (from p in contextLoad.MyAccounts
where p.AccountId == AccountId
select new MyResult Name = p.FirstName, Surname = p.Surname ).Single();
return q;
更新
我建议使用SingleOrDefault
而不是Single
。这将确保您
如果 Account 不存在而不是抛出异常,则得到 null
结果。
//
select new MyResult Name = p.FirstName, Surname = p.Surname ).SingleOrDefault();
//
【讨论】:
此代码假定查询返回一项且仅一项。如果集合中没有一个元素,Single
将引发异常。
成功了!我的目标是从帐户表中获取数据,并在网页中的文本框中填写详细信息:姓名、姓氏、地址等。我得到这样的数据:FirstNameTextBox.Text = MyResults.GetAccount(AccountId).FirstName; SurnameTextBox.Text = MyResults.GetAccount(AccountId).Surname; AddressTextBox.Text = MyResults.GetAccount(AccountId).Address; . . .等等......这是使用课程的最有效方式吗?似乎每次我填写一个文本框时我都必须打电话给一个班级......有没有更好的选择?非常感谢,【参考方案2】:
如果您不想为返回类型定义新对象,可以使用Tuple<string, string>
。
【讨论】:
【参考方案3】:另一个(不是最好的:))选项是返回一个数组:
public static string[] GetAccount(int AccountId)
LinqSqlDataContext contextLoad = new LinqSqlDataContext();
var q = (from p in contextLoad.MyAccounts
where p.AccountId == AccountId
select new Name = p.FirstName, Surname = p.Surname ).Single();
return new []q.Name, q.Surname;
【讨论】:
【参考方案4】:通过引用传入两个对象,您可以设置它们。
将其更改为 try 函数,作为代码味道较少的版本的示例
public static bool TryGetAccount(int AccountId, out String FirstName, out String Surname)
LinqSqlDataContext contextLoad = new LinqSqlDataContext();
var q = (from p in contextLoad.MyAccounts
where p.AccountId == AccountId
select new Name = p.FirstName, Surname = p.Surname ).SingleOrDefault();
FirstName=(q==null) ? null: q.Name;
Surname=(q==null) ? null: q.Surname;
return q!=null;
现在你可以做
string firstName;
string surname;
if (TryGetAccount(id, out firstName,out surname))
// firstName now equals the first name and surname now equals the surname
else
// Deal with value not found
【讨论】:
@the_joric 有点笼统的声明,没有任何解释,你现在让我很担心。 out 参数根据定义并不坏,许多编码人员认为它们是代码异味,因为它们会产生副作用。然而,它们确实有它们的用途——尤其是在 Try 风格的函数中。 See SO question @BobVale 很好奇,它们怎么会产生副作用?编译器在赋值之前停止使用out
参数,调用者必须明确指定out
,以便他们知道他们提供的任何变量都会被更改。副作用往往是不需要的状态更改。
@AdamHouldsworth 它们被认为是副作用,因为每个变量实际上都是作为对同一内存位置的引用传递给函数的,如果函数启动异步进程,则在函数返回后可能会更改该值。
@BobVale 谢谢,我必须记住这一点。我已经看到他们在我正在处理的当前代码库中徘徊。【参考方案5】:
如果您使用的是 .Net 4,您可以返回动态而不是字符串,并直接从返回的对象中获取这两个值。
【讨论】:
仅在同一个程序集中,或者如果您使用的是 InternalsVisibleToAttribute。匿名类型是隐式“内部”的,这会导致dynamic
出现问题。
这将产生涉及 DLR 的开销,因为它可以通过新类或 Tuple<string, string>
实现。此外,您还会失去 IntelliSense。【参考方案6】:
如果您不介意以这种方式使用返回的类型 tuple.Item1, tuple.Item2,将其返回为 Tuples 怎么样
【讨论】:
【参考方案7】:您可以使用 Hashtable 来避免创建新的结果类。 像这样的:
public static Hashtable GetAccount(int AccountId)
LinqSqlDataContext contextLoad = new LinqSqlDataContext();
var q = (from p in contextLoad.MyAccounts
where p.AccountId == AccountId
select new Name = p.FirstName, Surname = p.Surname ).Single();
return new Hashtable(q.FirstName, q.Surname);
你可以通过你的名字作为关键来获取姓氏。
【讨论】:
但是你可以很容易地返回一个new DictionaryEntry<string,string>(q.FirstName,q.Surname)
,它具有更强的打字优势,但是一个元组以上是关于在静态类中返回多个值的主要内容,如果未能解决你的问题,请参考以下文章