这是在IssueVision中的一段代码,用来实现观察者模式的!
public class IssueSubject : Component, ISubject//首先定义类IssueSubject继承自Component和ISubject,从这里和类名可以看出,此类是作为OBSERVER(观察者)模式中的目标(Subject)实现的.目标(Subject)对象要求实现对观察者(Observer)的注册(Register)和通知,Component类就是用来实现注册(Register)的.大多数目标(Subject)对象的实现并不是并非将观察者(Observer)的引用直接存储在自己的实例变量中,而是将此人物委托给一个单独的对象(通常为一个容器)Component类就是这样一个容器,下面代码显示了如何用Component类容器来存储对观察者(Observer)对象的引用注册(Register)public IssueSubject(IContainer Container) : this()
{
Container.Add(this);
}
其中构造函数public IssueSubject(IContainer Container) : this()后面的:this()
是什么意思,有什么意义,如果是base()我知道是调用或是说继承父类的构造函数,但这里用的是this(),如果是调用自己的构造函数的话,又缺少参数,因为本身是带参数的,而且这样做的意义是什么!不明白,希望高手赐教
public class IssueSubject : Component, ISubject//首先定义类IssueSubject继承自Component和ISubject,从这里和类名可以看出,此类是作为OBSERVER(观察者)模式中的目标(Subject)实现的.目标(Subject)对象要求实现对观察者(Observer)的注册(Register)和通知,Component类就是用来实现注册(Register)的.大多数目标(Subject)对象的实现并不是并非将观察者(Observer)的引用直接存储在自己的实例变量中,而是将此人物委托给一个单独的对象(通常为一个容器)Component类就是这样一个容器,下面代码显示了如何用Component类容器来存储对观察者(Observer)对象的引用注册(Register)public IssueSubject(IContainer Container) : this()
{
Container.Add(this);
}
其中构造函数public IssueSubject(IContainer Container) : this()后面的:this()
是什么意思,有什么意义,如果是base()我知道是调用或是说继承父类的构造函数,但这里用的是this(),如果是调用自己的构造函数的话,又缺少参数,因为本身是带参数的,而且这样做的意义是什么!不明白,希望高手赐教
{
InitializeComponent();
}
不过书上倒是出现过InitializeComponent();这个函数!
还有看过IssueVision源码的兄弟吗?见过的再说说意见!
我有这个程序的cs源码不过要运行在sql server 2000上才能安装!Issuevision是微软的一个救命程序!
代码可以上我的网络硬盘提取,一个是cs编写的一个是vb的!
http://www.51file.net/index.aspx
提取码:701205153
应该是这个意思.
比如:
clasee A
{
string ss="";
public A(string a)
{
ss = a;
}
public A():this("ssssssss")
{
}
}
public IssueSubject(IContainer Container) : this()表示的是 IssuSubject(Container) 调用自己类中的另一个函数中的代码(而这个函数this()就是此类中的默认构造函数 IssueSubject() ),
而恰好,这个默认构造函数 public IssueSubject() { } 没有显式写出来楼主理解了?
using System;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;
using ThreadHelper;
using IssueVision.localhost;namespace IssueVision
{
public enum SyncThread
{
MainThread = 0,
BackgroundThread = 1
} public class IssueSubject : Component, ISubject
{#region Delagate and Event Declarations
public delegate void PositionChangedEventHandler(object sender, EventArgs e);
public delegate void IssueDataChangedEventHandler(object sender, EventArgs e);
public delegate void ConflictDataChangedEventHandler(object sender, EventArgs e);
public delegate void LookupDataChangedEventHandler(object sender, EventArgs e);
public delegate void Synchronization_StartedEventHandler(object sender, EventArgs e);
public delegate void Synchronization_FinishedEventHandler(object sender, EventArgs e);
public delegate void DataChanged(IVDataSet newIssues); // PositionChanged is raised when a different issue is selected from the list
public virtual event PositionChangedEventHandler PositionChanged; // IssueDataChanged is raised when the data changes, either because the user
// edited the data, or because fresh data has arrived from the server
public virtual event IssueDataChangedEventHandler IssueDataChanged; // ConflictDataChanged changes when a conflict is resolved, or new conflicts are
// detected.
public virtual event ConflictDataChangedEventHandler ConflictDataChanged; // LookupDataChanged is raised when lookup data is downloaded from the server
public virtual event LookupDataChangedEventHandler LookupDataChanged; // Synchronization_Started is raised when a background synchronization starts.
public virtual event Synchronization_StartedEventHandler Synchronization_Started; // Synchronization_Started is raised when a background synchronization finishes.
public virtual event Synchronization_FinishedEventHandler Synchronization_Finished;
#endregion#region Internal Members
private IVDataSet m_dataSet = null;
private Timer tmrBackgroundThread;
private ThreadHelper.BackgroundWorker BackgroundWorkerThread; private bool m_isBackgroundThreadRunning = false;
private Control m_parent = null;
private bool m_showClosedIssues = true;
private DataView m_currentView = null;
private DataRowView m_currentItem = null;
private Hashtable m_conflictItems = null;
private string m_filterTable = string.Empty;
private string m_filterMember = string.Empty;
private string m_filterValue = string.Empty;
private int m_loggedInStafferID = 0;
private string m_loggedInDisplayName = string.Empty;
private bool m_isOnline = true;
private static DateTime m_lastModified = new DateTime(1900, 1, 1);
#endregion#region Public Properties
public IVDataSet.StaffersDataTable Staffers
{
get
{
return m_dataSet.Staffers;
}
} public DataRowView CurrentItem
{
get
{
return m_currentItem;
} set
{
m_currentItem = value;
if (PositionChanged != null)
{
PositionChanged(this, EventArgs.Empty);
}
}
} public DataView CurrentView
{
get
{
return m_currentView;
} set
{
m_currentView = value;
}
} public Hashtable ConflictItems
{
get
{
return m_conflictItems;
} set
{
m_conflictItems = value;
}
} public IVDataSet.ConflictsDataTable Conflicts
{
get
{
return m_dataSet.Conflicts;
}
} public bool HasConflicts
{
get
{
return Conflicts.Rows.Count > 0;
}
} public bool IsOnline
{
set
{
m_isOnline = value;
tmrBackgroundThread.Enabled = m_isOnline;
}
} public IVDataSet.IssuesDataTable Issues
{
get
{
return m_dataSet.Issues;
}
} public IVDataSet.IssueHistoryDataTable IssueHistory
{
get
{
return m_dataSet.IssueHistory;
}
} public IVDataSet.IssueTypesDataTable IssueTypes
{
get
{
return m_dataSet.IssueTypes;
}
} public Control Parent
{
get
{
return m_parent;
} set
{
m_parent = value;
}
} public bool ShowClosedIssues
{
get
{
return m_showClosedIssues;
} set
{
m_showClosedIssues = value;
PrepareCurrentView();
}
}
#endregion
private IContainer components = null; public IssueSubject(IContainer Container) : this()
{
Container.Add(this);
} public IssueSubject()
{
InitializeComponent();
} protected override void Dispose(bool disposing)
{
if (disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
} [DebuggerStepThroughAttribute()]
private void InitializeComponent()
{
components = new Container();
tmrBackgroundThread = new Timer(components);
BackgroundWorkerThread = new ThreadHelper.BackgroundWorker();
BackgroundWorkerThread.WorkerReportsProgress = true;
BackgroundWorkerThread.WorkerSupportsCancellation = true; tmrBackgroundThread.Tick += new EventHandler(this.tmrBackgroundThread_Tick); BackgroundWorkerThread.DoWork += new ThreadHelper.DoWorkEventHandler(this.OnDoWork);
BackgroundWorkerThread.RunWorkerCompleted += new ThreadHelper.RunWorkerCompletedEventHandler(this.OnCompleted);
}
#endregion#region IssueSubject Initialization
// Initialize the application's data and state
public void Initialize()
{
// load data
LoadIssueData();
UpdateLastModifiedDate(); if (!UserSettings.Instance.WorkOffline)
{
SendReceiveIssueData(SyncThread.MainThread);
} m_showClosedIssues = true; RenderIssuesToUI(); // set current user
DataRow[] rows = Staffers.Select("UserName = \'" + UserSettings.Instance.Username + "\'");
m_loggedInStafferID = (int)rows[0]["StafferID"];
m_loggedInDisplayName = (string)rows[0]["DisplayName"];
tmrBackgroundThread.Interval = int.Parse(ConfigurationSettings.AppSettings["SyncInterval"]);
}
#endregion#region Background Update Code
// tmrBackgroundThread.Tick: background thread is started on timer tick
private void tmrBackgroundThread_Tick(object sender, EventArgs e)
{
if (!m_isBackgroundThreadRunning)
{
SendReceiveIssueData(SyncThread.BackgroundThread);
}
} // entry point for Send/Receive data
public void SendReceiveIssueData(SyncThread behavior)
{
if (Synchronization_Started != null)
{
Synchronization_Started(this, EventArgs.Empty);
} if (behavior == SyncThread.BackgroundThread)
{
m_isBackgroundThreadRunning = true;
BackgroundWorkerThread.RunWorkerAsync(m_lastModified);
}
else
{
IVDataSet newIssues = GetNewIssues(m_lastModified);
MergeNewIssues(newIssues);
}
} // BackgroundWorkerThread.DoWork: this method is run on the background thread to do its work
private void OnDoWork(object sender, ThreadHelper.DoWorkEventArgs doWorkArgs)
{
DateTime lastAccessed = (DateTime)doWorkArgs.Argument;
doWorkArgs.Result = GetNewIssues(lastAccessed);
} // sends and received data to/from the web service
private IVDataSet GetNewIssues(DateTime lastAccessed)
{
IVDataSet newIssues = null; try
{
DataSet changesDataSet = m_dataSet.GetChanges(DataRowState.Added | DataRowState.Modified);
newIssues = WebServicesLayer.SendReceiveIssues(changesDataSet, lastAccessed);
}
catch
{
// Eat this exception. It is logged on the service side, and the caller of this
// method tests if newIssues is null to decide whether the service is currently
// available.
} return newIssues;
} // BackgroundWorkerThread.RunWorkerCompleted: This method runs on the timer thread
// when the background thread finishes it's work
private void OnCompleted(object sender, ThreadHelper.RunWorkerCompletedEventArgs completedArgs)
{
// newIssues is return from the background thread to the timer thread
IVDataSet newIssues = (IVDataSet)completedArgs.Result; // Parent.Invoke passes the newIssues data to MergeNewIssues on the MainForm thread
m_parent.Invoke(new DataChanged(this.MergeNewIssues), new object[]{newIssues});
}
#endregion
// Merge the issue data
private void MergeNewIssues(IVDataSet newIssues)
{
// Process new data, if any
if (newIssues != null && newIssues.HasChanges(DataRowState.Unchanged))
{
m_dataSet.Merge(newIssues, false);
m_dataSet.AcceptChanges();
UpdateLastModifiedDate();
RenderIssuesToUI();
} m_isBackgroundThreadRunning = false; if (Synchronization_Finished != null)
{
Synchronization_Finished(this, EventArgs.Empty);
}
} private void RenderIssuesToUI()
{
PrepareLookupTables();
PrepareConflicts();
PrepareCurrentView();
} public void SetFilter(string filterTable, string filterMember, string filterValue)
{
m_filterTable = filterTable;
m_filterMember = filterMember;
m_filterValue = filterValue; PrepareCurrentView();
} // Filters current view to hide/show closed issues
private void PrepareCurrentView()
{
string filterString = string.Empty; if (m_filterValue != string.Empty)
{
filterString = m_filterMember + " = " + m_filterValue;
} if (!ShowClosedIssues)
{
if (filterString == string.Empty)
{
filterString = "IsOpen = 1";
}
else
{
filterString += " AND IsOpen = 1";
}
} if (m_filterTable == "Issues" || m_filterTable == string.Empty)
m_currentView = new DataView(Issues);
else
m_currentView = new DataView(Conflicts); m_currentView.RowFilter = filterString;
m_currentView.Sort = "IssueTypeID"; if (IssueDataChanged != null)
{
IssueDataChanged(this, EventArgs.Empty);
}
} private void PrepareConflicts()
{
if (Conflicts != null && Conflicts.Rows.Count > 0)
{
ConflictItems = new Hashtable(Conflicts.Rows.Count + 1); foreach (IVDataSet.ConflictsRow clientRow in Conflicts.Rows)
{
clientRow.HasConflicts = true;
IVDataSet.IssuesRow serverRow = (IVDataSet.IssuesRow)Issues.Rows.Find(clientRow.IssueID);
ConflictItems.Add(clientRow.IssueID, new ConflictItem(clientRow, serverRow));
} if (ConflictDataChanged != null)
{
ConflictDataChanged(this, EventArgs.Empty);
}
}
} private void PrepareLookupTables()
{
if (m_dataSet.Staffers.Count == 0 && m_dataSet.IssueTypes.Count == 0)
{
IVDataSet lookupTables = WebServicesLayer.GetLookupTables();
m_dataSet.Merge(lookupTables, true); if (LookupDataChanged != null)
{
LookupDataChanged(this, EventArgs.Empty);
}
}
} private void UpdateLastModifiedDate()
{
DataView dv = new DataView(Issues);
dv.Sort = "DateModified DESC";
if (dv.Count > 0)
m_lastModified = (DateTime)dv[0]["DateModified"];
}#endregion#region Issue Adding, Updating and Resolving
// Add new issue
public void AddIssue(int stafferID, int issueTypeID, string title, string description)
{
DataRow rowStaffer = m_dataSet.Staffers.Select("StafferId=" + stafferID.ToString())[0];
DataRow rowIssueType = m_dataSet.IssueTypes.Select("IssueTypeID=" + issueTypeID.ToString())[0]; IVDataSet.IssuesRow row = m_dataSet.Issues.AddIssuesRow(stafferID,
issueTypeID,
title,
description,
DateTime.Now,
DateTime.MinValue,
true,
DateTime.Now,
(string)rowStaffer["UserName"],
(string)rowStaffer["DisplayName"],
(string)rowIssueType["IssueType"],
false,
true);
if (IssueDataChanged != null)
{
IssueDataChanged(this, EventArgs.Empty);
}
} public void UpdateIssue(int issueID, int stafferID, string stafferName, string comment, bool isOpen)
{
// Find this issue in the current dataset
DataRow dr = m_dataSet.Issues.Rows.Find(issueID);
dr.BeginEdit(); if (isOpen)
{
dr["IsOpen"] = 1;
}
else
{
dr["IsOpen"] = 0;
} dr["StafferID"] = stafferID;
dr["DisplayName"] = stafferName;
dr.EndEdit(); if (comment.Trim() != string.Empty)
{
m_dataSet.IssueHistory.AddIssueHistoryRow(m_loggedInStafferID, issueID, comment, DateTime.Now, m_loggedInDisplayName);
if (IssueDataChanged != null)
{
IssueDataChanged(this, EventArgs.Empty);
}
}
} public void ResolveConflict(ConflictItem conflict, bool keepClientVersion)
{
if (keepClientVersion)
{
conflict.ServerVersion["StafferID"] = conflict.ClientVersion["StafferID"];
conflict.ServerVersion["DisplayName"] = conflict.ClientVersion["DisplayName"];
conflict.ServerVersion["IsOpen"] = conflict.ClientVersion["IsOpen"];
} Conflicts.Rows.Remove(conflict.ClientVersion);
ConflictItems.Remove(conflict.ServerVersion["IssueID"]);
((IVDataSet.IssuesRow)conflict.ServerVersion).HasConflicts = false; if (ConflictDataChanged != null)
{
ConflictDataChanged(this, EventArgs.Empty);
} if (IssueDataChanged != null)
{
IssueDataChanged(this, EventArgs.Empty);
}
}
#endregion#region DataSet Serialization Methods
public void SaveIssueData()
{
string filePath = Application.UserAppDataPath + "\\" + ConfigurationSettings.AppSettings["DataSetFileName"];
SerializationHelper.Serialize(m_dataSet, filePath);
} private void LoadIssueData()
{
m_dataSet = GetOfflineData(); if (m_dataSet == null)
{
m_dataSet = new IVDataSet();
} m_dataSet.DataSetName = "IssueSubject"; if (LookupDataChanged != null)
{
LookupDataChanged(this, EventArgs.Empty);
}
} public static IVDataSet GetOfflineData()
{
IVDataSet ivDataSet = null; try
{
string filePath = Application.UserAppDataPath + "\\" + ConfigurationSettings.AppSettings["DataSetFileName"];
ivDataSet = (IVDataSet)SerializationHelper.Deserialize(filePath);
}
catch
{
// Eat this exception. The caller of this method tests if ivDataSet is null to decide whether
// offline data is available.
} return ivDataSet;
}
#endregion#region Reporting methods
public int GetClosedCount()
{
char[] delimiter = " ".ToCharArray();
string[] filterParts = m_currentView.RowFilter.Split(delimiter);
DataView dv = new DataView(Issues); if (filterParts[0] == "StafferID")
{
dv.RowFilter = "StafferID = " + filterParts[2] + " AND IsOpen = 0";
}
else
{
dv.RowFilter = "IsOpen = 0";
} return dv.Count;
} public int GetEscalatedCount()
{
int open = GetOpenCount();
return (int)Math.Round(open * 0.3);
} public int GetOpenCount()
{
char[] delimiter = " ".ToCharArray();
string[] filterParts = m_currentView.RowFilter.Split(delimiter);
DataView dv = new DataView(Issues); if (filterParts[0] == "StafferID")
{
dv.RowFilter = "StafferID = " + filterParts[2] + " AND IsOpen = 1";
}
else
{
dv.RowFilter = "IsOpen = 1";
} return dv.Count;
}
#endregion
}
}
==================================
public IssueSubject(IContainer Container) : this()表示的是 IssuSubject(Container) 调用自己类中的另一个函数中的代码(而这个函数this()就是此类中的默认构造函数 IssueSubject() ),
而恰好,这个默认构造函数 public IssueSubject() { } 没有显式写出来楼上已经回答,补重一点这样写的好处是避免代码膨胀
----------
正解..