21 限制類型的可見性
不是每個類型都需要Public。你應給你的類型最少的可見度來達到你的目的,內部或私有類能實現公共的接口。很多獨立的類應當創建為內部的。你可以使用protected或私有嵌套類進一步來限制其可見性,可見性越小,當你之後更新時,整個系統的更改也就越少,越少的地方訪問你的代碼,你修改的地方也就越少。
只暴露那些需要暴露的。對於可見性小的類,嘗試使用公共接口來暴露。
// For illustration, not complete source public class List: IEnumerable { private class Enumerator : IEnumerator { // Contains specific implementation of // MoveNext(), Reset(), and Current. public Enumerator(List storage) { // elided } } public IEnumerator GetEnumerator() { return new Enumerator (this); } // other List members. }
public interface IPhoneValidator
{
bool ValidateNumber(PhoneNumber ph);
}
internal class USPhoneValidator : IPhoneValidator
{
public bool ValidateNumber(PhoneNumber ph)
{
// perform validation.
// Check for valid area code, exchange.
return true;
}
} public static class Extensions
{
public static void ForAll(
this IEnumerable sequence,
Action action)
{
foreach (T item in sequence)
action(item);
}
}
// usage
foo.ForAll((n) => Console.WriteLine(n.ToString())); public struct URLInfo : IComparable, IComparable { private string URL; private string description; #region IComparable Members public int CompareTo(URLInfo other) { return URL.CompareTo(other.URL); } #endregion #region IComparable Members int IComparable.CompareTo(object obj) { if (obj is URLInfo) { URLInfo other = (URLInfo)obj; return CompareTo(other); } else throw new ArgumentException( "Compared object is not URLInfo"); } #endregion }
interface IMsg
{
void Message();
}
public class MyClass : IMsg
{
public void Message()
{
Console.WriteLine("MyClass");
}
}Message()方法現在是MyClass類的公共接口。Message也可以通過IMsg指針來訪問。現在我們來增加一個派生類:public class MyDerivedClass : MyClass
{
public void Message()
{
Console.WriteLine("MyDerivedClass");
}
} public class MyClass : IMsg
{
public virtual void Message()
{
Console.WriteLine("MyClass");
}
}
public class MyDerivedClass : MyClass
{
public override void Message()
{
Console.WriteLine("MyDerivedClass");
}
} public class MyDerivedClass2 : MyClass
{
public sealed override void Message()
{
Console.WriteLine("MyDerivedClass");
}
} public class MyClass2 : IMsg
{
protected virtual void OnMessage()
{
}
public void Message()
{
OnMessage();
Console.WriteLine("MyClass");
}
} public class DefaultMessageGenerator
{
public void Message()
{
Console.WriteLine("This is a default message");
}
}
public class AnotherMessageGenerator :
DefaultMessageGenerator, IMsg
{
// No explicit Message() method needed.
}public class LoggerEventArgs : EventArgs
{
public string Message { get; private set; }
public int Priority { get; private set; }
public LoggerEventArgs(int p, string m)
{
Priority = p;
Message = m;
}
}
public class Logger
{
static Logger()
{
theOnly = new Logger();
}
private Logger()
{
}
private static Logger theOnly = null;
public static Logger Singleton
{
get { return theOnly; }
}
// Define the event:
public event EventHandler Log;
// add a message, and log it.
public void AddMsg(int priority, string msg)
{
// This idiom discussed below.
EventHandler l = Log;
if (l != null)
l(this, new LoggerEventArgs(priority, msg));
}
} class ConsoleLogger
{
static ConsoleLogger()
{
Logger.Singleton.Log += (sender, msg) =>
{
Console.Error.WriteLine("{0}:\t{1}",
msg.Priority.ToString(),
msg.Message);
};
}
}