这是在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(),如果是调用自己的构造函数的话,又缺少参数,因为本身是带参数的,而且这样做的意义是什么!不明白,希望高手赐教

解决方案 »

  1.   

    代码中应该有还有个构造函数吧?不然怎么能编译呢.public IssueSubject()
    {
    InitializeComponent();
    }
      

  2.   

    嗯,有可能,真正的源码我没有见过,我只是在网上见到这样一段代码,书上也没有完整的代码!
    不过书上倒是出现过InitializeComponent();这个函数!
    还有看过IssueVision源码的兄弟吗?见过的再说说意见!
    我有这个程序的cs源码不过要运行在sql server 2000上才能安装!Issuevision是微软的一个救命程序!
    代码可以上我的网络硬盘提取,一个是cs编写的一个是vb的!
    http://www.51file.net/index.aspx
    提取码:701205153
      

  3.   

    我把文件放到共享里去了:http://lovko.51file.net大家可以直接下载不需要提取了!
      

  4.   

    有2个构造函数的,一个是IssueSubject(IContainer Container),一个是IssueSubject(),前者加上:this()表示构造函数链,在调用IssueSubject(IContainer Container)之前调用IssueSubject().
    应该是这个意思.
    比如:
    clasee A
    {
        string ss="";
        public A(string a)
        {
            ss = a;
        }
        public A():this("ssssssss")
        {
           
        }
    }
      

  5.   

    兄弟,希望等得到你的100分,呵呵首先,c# 里的 this 代表正在运行的当前实例,也就是这个类的一个实例(只不过系统是自己生成,不用我们显式声明和初始化)第二, c#类中的默认构造函数(也就是无形参,无实现体的)在代码中是可以缺省的,我们可以不用代码写出来。(如果缺省,程序在编译的时候,系统会为我们加上这个构造函数)第三,对构造函数 Func(para):this()来说 ,表示的是Func构造函数可以调用 this()函数里的代码,而this()就是Func的无行参的重载函数。 必须这样写,而不能写成Func(para):Func()最后,我们可以知道
    public IssueSubject(IContainer Container) : this()表示的是 IssuSubject(Container) 调用自己类中的另一个函数中的代码(而这个函数this()就是此类中的默认构造函数 IssueSubject() ),
    而恰好,这个默认构造函数 public IssueSubject() { } 没有显式写出来楼主理解了?
      

  6.   

    //刚找到的代码,是有我说的那个构造函数的,继承Component,一般都有InitializeComponent函数的
    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
      

  7.   

    #region Component Designer generated code
    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
      

  8.   

    #region Data Merging/Display Methods
    // 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
    }
    }
      

  9.   

    兄弟,希望等得到你的100分,呵呵
    ==================================
    public IssueSubject(IContainer Container) : this()表示的是 IssuSubject(Container) 调用自己类中的另一个函数中的代码(而这个函数this()就是此类中的默认构造函数 IssueSubject() ),
    而恰好,这个默认构造函数 public IssueSubject() { } 没有显式写出来楼上已经回答,补重一点这样写的好处是避免代码膨胀
      

  10.   

    this()就是调用自己的无参构造函数
      

  11.   

    this()就是调用自己的无参构造函数
    ----------
    正解..