MS'自己的console.cs具有以下函数,由IsInput / Output / ErrorRedirected API使用。
private static bool IsHandleRedirected(IntPtr ioHandle) {
// Need this to use GetFileType:
SafeFileHandle safeIOHandle = new SafeFileHandle(ioHandle, false);
// If handle is not to a character device, we must be redirected:
int fileType = Win32Native.GetFileType(safeIOHandle);
if ((fileType & Win32Native.FILE_TYPE_CHAR) != Win32Native.FILE_TYPE_CHAR) // <--- ??
return true;
// We are on a char device.
// If GetConsoleMode succeeds, we are NOT redirected.
int mode;
bool success = Win32Native.GetConsoleMode(ioHandle, out mode);
return !success;
}
我不理解// <--- ??
标记(由我)标记的逻辑。 if (fileType != Win32Native.FILE_TYPE_CHAR) return true;
会有意义,但我不会理解为什么在比较之前它会被& Win32Native.FILE_TYPE_CHAR
掩盖。
为了使其更加混乱,常量FILE_TYPE_CHAR
是单个位0x0002
,它也由FILE_TYPE_PIPE = 0x0003
共享,因此有问题的if
语句不会return true;
1}}如果文件句柄引用了一个管道(可能依赖GetConsoleMode
后来失败了??)。
任何深入了解代码编写方式的原因都将非常受欢迎。感谢。
答案 0 :(得分:0)
使用标记枚举时,它曾经是一种常用技术。
您在输入值和要检查的标志之间使用按位,并将结果与标志本身进行比较。如果输入值包含标志,则条件为真,否则,条件为假。
让我用一个简单的例子说明:
假设你有这个枚举:
[Flags]
enum test
{
None = 0, // 0000
One = 1, // 0001
Two = 2, // 0010
Four = 4, // 0100
Eight = 8 // 1000
}
你有一个想要测试的价值。让我们说13.当您将13转换为四位二进制数时,您得到1101 - 所以您可以这样做:
var input = 13;
if(((test)input & test.One) == test.One) // that's testing if 1101 & 0001 = 0001
{
// The result of this condition is true, since 13 is an odd number.
}
但是,从.Net 4.0开始,您只需使用HasFlag
方法:
if(input.HasFlag(test.One))
{
// The result of this condition is true, since 13 is an odd number.
}
有关详细信息,请参阅Ending the Great Debate on Enum Flags