У меня есть объект, который переопределяет iComparable, а также переопределяет toString().
Когда вызывается конструктор, он также вызывает toString(), но не достигает точек останова в методе toString().
Метод toString() также вызывается при выполнении каждой строки конструктора, и как только свойство DataSource обновляется, он получает данные из базы данных и выдает неожиданные результаты.
Я доказал это с помощью ведения журнала environment.stacktrace для каждого вызова.
Является ли это ожидаемым поведением, и есть ли возможность вызывать toString() только тогда, когда я вызываю его явно, а не автоматически.
Код для класса ниже
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Business.Data;
namespace PfWToEpayfactGIF
{
class PsPayChangeDetails : IComparable<PsPayChangeDetails>
{
public DateTime EffectiveDate { get; set; }
public String Code { get; set; }
public string ChangeType { get; set; }
public int DataSourceX { get; set; }
private string gradeID;
private string gradeSubCode;
private string gradePercentage;
private string IDField;
private string salary;
private string maxOTRateType;
private string lWeightType;
private string onTempPromotion;
private string RTIHoursInd;
private string paygroupID;
private string classification;
private string hoursPayable;
private string workingPatternID;
private string OSPSchemeNo;
private string milestoneDate;
private string employeeNo;
public PsPayChangeDetails(string code, DateTime effectiveDate, string changeType, int groupSource)
{
EffectiveDate = effectiveDate;
Code = code;
ChangeType = changeType;
DataSourceX = groupSource;
}
public void ReadLine(string[] line)
{
employeeNo = line[0] != string.Empty ? line[0] : employeeNo;
try
{
if (Code == "E420")
{
gradeID = line[4] != string.Empty ? line[4] : gradeID;
gradeSubCode = line[5] != string.Empty ? line[5] : gradeSubCode;
gradePercentage = line[6] != string.Empty ? line[6] : gradePercentage;
IDField = line[7] != string.Empty ? line[7] : IDField;
salary = line[8] != string.Empty ? line[8] : salary;
maxOTRateType = line[9] != string.Empty ? line[9] : maxOTRateType;
lWeightType = line[10] != string.Empty ? line[10] : lWeightType;
onTempPromotion = line[11] != string.Empty ? line[11] : onTempPromotion;
RTIHoursInd = line[12] != string.Empty ? line[12] : RTIHoursInd;
}
else
{
paygroupID = line[4] != string.Empty ? line[4] : paygroupID;
classification = line[5] != string.Empty ? line[5] : classification;
hoursPayable = line[6] != string.Empty ? line[6] : hoursPayable;
workingPatternID = line[7] != string.Empty ? line[7] : workingPatternID;
OSPSchemeNo = line[8] != string.Empty ? line[8] : OSPSchemeNo;
milestoneDate = line[9] != string.Empty ? line[9] : milestoneDate;
}
}
catch (IndexOutOfRangeException)
{
//ignore the exception as its telling us we dont have all the fields which is fine.
}
}
public override string ToString()
{
using (System.IO.StreamWriter write = new System.IO.StreamWriter(@"c:\temp\test.txt", true))
{
write.WriteLine(Environment.StackTrace);
}
string output = $"{employeeNo},{Code},{EffectiveDate.ToString("dd/MMM/yyyy")},{ChangeType},";
if (Code == "E420")
{
output += $"{gradeID},{gradeSubCode},{gradePercentage},{IDField},{salary},{maxOTRateType},{lWeightType},{onTempPromotion},{RTIHoursInd}";
}
else
{
using (DataEntities db = new DataEntities(DataSourceX))
{
if (paygroupID == null)
{
string partTime = workingPatternID == "PT" ? "Y" : "N";
paygroupID = db.PayGroupEESetting.Where(pge => pge.PartTimeInd == partTime && pge.EnteredDate == db.PayGroupEESetting.Where(pg => pg.PayGroup == pge.PayGroup && pg.EnteredDate <= EffectiveDate).Max(pg => pg.EnteredDate)).OrderBy(pge => pge.PayGroup).FirstOrDefault().PayGroup;
}
workingPatternID = workingPatternID == null ? "FT" : "PT";
if (OSPSchemeNo == null)
{
OSPSchemeNo = db.OSPScheme.Min(o => o.SchemeNo).ToString();
}
}
output += $"{paygroupID},{classification},{hoursPayable},{workingPatternID},{OSPSchemeNo},{milestoneDate}";
}
return output;
}
public int CompareTo(PsPayChangeDetails other)
{
if (this.Code == other.Code)
{
return this.EffectiveDate.CompareTo(other.EffectiveDate);
}
else
{
return this.Code.CompareTo(other.Code);
}
}
}
}
Спасибо за любую помощь.
Бен
ToString
. Он не вызывается автоматически только потому, что он есть, его нужно где-то вызывать. - person HimBromBeere   schedule 15.12.2016ToString
?ToString
может вызываться много, много раз, чего вы не ожидаете. Я настоятельно рекомендую использовать разные методы для ОБОИХ этих действий и не переопределять базовыеobject
методы, которые могут быть вызваны вне вашего контроля. - person D Stanley   schedule 15.12.2016ToString
просто должен представлять ваш текущий объект в виде строки. Поскольку это перегрузкаobject.ToString
, любой код, который получает ссылку на ваш объект и вызываетToString
, будет выполнять этот код. Этот код может находиться в другом потоке, присоединенных процессах (например, отладчике) и т. д., что очень затруднит отладку. Так что, если у вас вопрос, почему это называется, когда я его не называю, вы никогда не узнаете. - person D Stanley   schedule 15.12.2016