我对c#很新,以前试图忽略类并构建我的小程序,在结构上更类似于PHP。到达路障后,我正试图重新开始并正确处理问题OO。我正在处理一个长文件,并且在一个循环中,每次满足某些条件时,我想创建一个新对象。如何创建新对象,而无需指定唯一名称?
Referral ObjectName = new Referral(string, string, int);
其次,一旦完成,字符串& int设置它们的相应对象属性,我如何通过一个属性将该类唯一 - 然后按类别对该类进行排序?
如果这些是基本问题,我很抱歉,我花了大量的时间来首先尝试通过谷歌和教科书来解决这个问题。如果只有C#允许具有不同类型的多维数组!
非常感谢你!
PS。我的意思是提取一个唯一对象列表。
所有这些答案虽然有用,但似乎涉及创建IEnumerables的阴影集。班级本身没有办法做到这一点吗?
尝试第一个解决方案,由Earwicker提供,将每个对象从循环内添加到List中,当我尝试将元素的属性写入控制台时,我得到ClassName + Referral。我能做错什么? - 解决了。仍然需要.property
仍在工作。 。
答案 0 :(得分:7)
C#确实允许无类型数组。所有对象最终都来自object
,因此您使用object
的数组或容器。但这很少是必要的。你有多少个类型的对象?
在循环块中,您可以完全像在该行代码中那样创建对象(除了语法已修复),并且每次循环时它都是一个新对象。要在循环外保留所有对象,可以将其添加到容器中:
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
的值命名的“插槽”中。重复项将以静默方式相互覆盖。
答案 1 :(得分:3)
首先,您需要花一些时间熟悉语言的基础知识才能提高效率。我建议你花点时间阅读C#,然后再深入了解 - 否则你会花很多时间来转动轮子 - 或者重新发明它们:)
但是这里有一些让你入门的信息。
通常,在C#中,您创建表示程序元素的类 - 包括用于表示程序打算操作的信息(数据)的类。您应该考虑使用一个,因为它将使数据操作更清晰,更易于管理。我会建议避免使用无类型的多维数组结构,因为这些结构很快就会变得非常难以使用。
您可以使用自动属性和简单的构造函数在C#中轻松创建Referall类:
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 );
答案 2 :(得分:2)
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&lt; Referral&gt;。
上的Sort()方法答案 3 :(得分:1)
您可以创建没有引用的对象,但稍后您将无权访问它:
new Referral(string, string, int);
如果您希望将它们放在数组/列表中,则这些不同类型需要具有公共基类。这被称为polimorfism,这是面向对象编程中非常重要的概念。
答案 4 :(得分:0)
使用c#时不能忽略类。不要抗拒变化!
你真的不需要在这里创建课程吗?你真的不需要给它起个名字吗? C#允许松散打字,但类型安全是一件好事。
答案 5 :(得分:0)
我不完全明白你要做什么。但也许LINQ正是你所寻找的。周围有大量文档,但作为快速“预告片”,请查看101 Linq samples on MSDN
答案 6 :(得分:0)
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);
}