【问题标题】:c# looping object creationc# 循环对象创建
【发布时间】:2009-07-21 18:06:52
【问题描述】:

我是 C# 的新手,之前试图忽略类并构建我的小程序,其结构更类似于 PHP。遇到障碍后,我试图重新开始并正确解决问题 OO。我正在处理一个长文件,并且在循环中,每次满足某些条件时,我都想创建一个新对象。我怎样才能让它创建一个新对象,而不必指定一个唯一的名称?

Referral ObjectName = new Referral(string, string, int);

其次,一旦完成,并且字符串和 int 设置了它们适当的对象属性,我如何才能通过一个属性唯一化类,然后按另一个属性对类进行排序?

如果这些是基本问题,我很抱歉,我已经花费了大量时间首先尝试通过谷歌和教科书自行解决。如果只有 C# 允许具有不同类型的多维数组!

非常感谢!

PS。我的意思是提取一个独特对象的列表。

所有这些答案虽然很有帮助,但似乎涉及创建 IEnumerables 的影子集。类本身就没有办法做到这一点吗?

尝试由 Earwicker 提供的第一个解决方案,将每个对象从循环内添加到列表中,当我尝试将元素的属性写入控制台时,我得到了 ClassName+Referral。我可能做错了什么? - 解决了。仍然需要.property

仍在工作。 . .

【问题讨论】:

标签: c# variables class object sorting


【解决方案1】:

C# 确实允许无类型数组。所有对象最终都派生自object,因此您使用objects 的数组或容器。但很少有必要。你有多少类型的对象?

在循环块中,您可以像在该行代码中一样创建一个对象(语法固定除外),并且每次循环时它都会是一个新对象。要使所有对象在循环之外可用,您可以将其添加到容器中:

List<Referral> referrals = new List<Referral>();

// in the loop:
Referral r = new Referral(str1, str2, num1);
referrals.Add(r);

假设Referral 有一个名为Cost 的数字属性。

referrals.Sort((l, r) => l.Cost - r.Cost);

按成本排序。

为了通过某些键确保唯一性,您可能会发现选择更合适的容器更容易。

Dictionary<string, Referral> referrals = new List<Referral>();

// in the loop:
Referral r = new Referral(str1, str2, num1);
referrals[str1] = r;

这会将推荐存储在以str1 的值命名的“槽”中。重复项会默默地相互覆盖。

【讨论】:

  • 使用 lambda 进行排序意味着您将获得 LINQ 支持,在这种情况下 OrderBy 语法 (imo) 更易于使用。
  • 是的,但对于大型数据集,List 上的Sort 可能会更快一些 - 取决于哪个对您更重要。
【解决方案2】:

首先,您需要花一些时间熟悉该语言的基础知识才能提高工作效率。我建议您在深入了解 C# 之前花点时间阅读 - 否则您将花费​​大量时间旋转您的轮子 - 或重新发明它们:)

但这里有一些信息可以帮助您入门。

通常,在 C# 中,您创建类来表示程序的元素 - 包括那些用于表示程序打算操作的信息(数据)的类。你真的应该考虑使用一个,因为它会使数据操作更清晰、更易于管理。我建议避免像某些人建议的那样,避免使用无类型的多维数组结构,因为这些结构很快就会变得非常难以使用。

您可以使用自动属性和简单的构造函数在 C# 中轻松创建引用类:

public class Referall
{
   // these should be named in line with what they represent...
   public string FirstString   { get; set; }
   public string AnotherString { get; set; }
   public int    SomeValue     { get; set; }

   public Referall( string first, string another, int value )
   {
       FirstString = first;
       AnotherString = another;
       SomeValue = value;
   }
}

您可以在创建它们时将它们添加到字典中 - 字典可以通过唯一的属性来键入。字典允许您根据唯一键存储对象:

Dictionary<string,Referall> dict = new Dictionary<string,Referall>();

在处理项目时,可以将它们添加到字典中:

Referall ref = new Referall( v1, v2, v3 );
// add to the dictionary, keying on FirstString...
dict.Add( ref.FirstString, ref );

如果完成后需要对字典中的项目进行排序,可以在 C# 3.0 中使用 LINQ:

IEnumerable<Referall> sortedResults =
       dict.Values.OrderBy( x => x.AnotherString );

您也可以使用 ThenBy() 进行多维度排序:

IEnumerable<Referall> sortedResults =
       dict.Values.OrderBy( x => x.AnotherString )
                  .ThenBy( x => x.SomeValue );

【讨论】:

    【解决方案3】:
    List<Referral> referrals = new List<Referral>();
    
    for (...)
    {
        referrals.Add(new Referral(string1, string2, number1));
    }
    

    然后,如果您使用的是 Linq(我强烈建议您这样做),您可以这样做:

    IEnumerable<Referral> sorted = referrals.OrderBy(x => x.string1).ThenBy(x => x.string2);
    

    否则,您可以在 List 上使用 Sort() 方法。

    【讨论】:

      【解决方案4】:

      您可以在没有引用的情况下创建对象,但以后您将无法访问它:

      new Referral(string, string, int);
      

      如果你想把它们放在一个数组/列表中,这些不同的类型需要有一个共同的基类。这就是所谓的polimorfism,是OO编程中一个非常重要的概念。

      【讨论】:

      • 我只想添加它而不是基类,您可以使用接口。尤其重要,因为 C# 不支持多重继承。
      【解决方案5】:

      在使用 c# 时不能忽略类。不要抗拒改变!

      你真的不需要在这里创建一个类吗?你真的不需要给它一个名字吗? C# 确实允许松散类型,但类型安全是一件好事。

      【讨论】:

      • 你是什么意思“松散的打字”?
      • 可能意味着动态或运行时类型。 C# 对静态(编译时)类型有很强的支持,这意味着你告诉编译器(或者它计算出)存储在变量中的对象的类型,允许它优化并发现许多简单的错误。
      • Earwicker 是正确的,松散或弱类型与强类型相反:en.wikipedia.org/wiki/Weak_typing
      【解决方案6】:

      我不完全理解你想要做什么。但也许 LINQ 是您正在寻找的。周围有大量文档,但作为一个快速的“预告片”,请查看101 Linq samples on MSDN

      【讨论】:

        【解决方案7】:

        C# 包含一个称为“迭代器块”的奇妙功能。你想要做的是使用yield 关键字来创建一个你的Referal 对象的Enumerable,就像这样(不是我正在制作文件格式和属性名称,因为你没有分享):

        public class Referral
        {
            public Guid id { get; private set; } // "uniquify"
            public int ReferringId { get; set; }
            public string ReferrerText { get; set; }
            public string ReferrerDescription { get; set; }
        
            private Referral()
            {
               id = new Guid();
            }
        
            private Referral(string Text, string Description, int ReferringId) : this()
            {
                this.ReferrerText = Text;
                this.ReferrerDescription = Description;
                this.ReferringId = ReferringId;
            }
        
            public static IEnumerable<Referral> GetReferrals(string fileName) 
            {
                using (var rdr = new StreamReader(fileName))
                {
                    var next = new Referrer();
        
                    int state = 0;
                    string line;
                    while ( (line = rdr.ReadLine() ) != null)
                    {
                        switch (state)
                        {
                            case 0:
                                next.ReferrerText = line;
                                state = 1;
                                break;
        
                            case 1:
                                next.ReferrerDescription = line;
                                state = 2;
                                break;
        
                            case 2:
                                next.ReferringId = int.Parse(line);
                                yield return next;
                                next = new Referral();
                                state = 0;
                                break;
                        }
                    }                
                }
            }
        }
        

        现在您想要对推荐进行排序并出于某种目的对它们进行推测枚举。您可以像这样轻松地做到这一点:

        foreach (var referral in Referral.GetReferrals(@"C:\referralfile.txt").OrderBy( r => r.Text ) )
        {
            OutputReferral(referral);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-06-14
          • 2012-11-29
          • 2015-02-23
          • 2016-11-11
          • 2020-08-08
          • 2015-02-04
          相关资源
          最近更新 更多