669 lines
24 KiB
C#
669 lines
24 KiB
C#
using Microsoft.CSharp.RuntimeBinder;
|
||
//using Newtonsoft.Json;
|
||
using System.Collections.ObjectModel;
|
||
using System.Drawing.Imaging;
|
||
using System.Dynamic;
|
||
using System.Linq.Expressions;
|
||
using System.Reflection;
|
||
using System.Runtime.CompilerServices;
|
||
using System.Runtime.ExceptionServices;
|
||
using System.Runtime.InteropServices;
|
||
using System.Runtime.Serialization.Formatters.Binary;
|
||
|
||
public static class StaticHelper
|
||
{
|
||
/// <summary>
|
||
/// 数值转换为byte数组 高位在前,低位在后
|
||
/// </summary>
|
||
/// <param name="number"></param>
|
||
/// <param name="size"></param>
|
||
/// <returns></returns>
|
||
public static byte[] IntToBytes(this int number, int size = 2)
|
||
{
|
||
byte[] result = new byte[size];
|
||
|
||
int temp = size;
|
||
while (temp > 0)
|
||
{
|
||
result[size - temp] = (byte)(number >> ((temp - 1) * 8) & 0xff);
|
||
|
||
temp--;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 字节数组转换为整数
|
||
/// </summary>
|
||
/// <param name="data">字节数组</param>
|
||
/// <param name="HtL">true:数组序号低的在高位 false:数组序号低的在低位</param>
|
||
/// <returns></returns>
|
||
public static int BytesToInt(this byte[] data, bool HtL = true)
|
||
{
|
||
int res = 0;
|
||
|
||
for (int i = 0; i < data.Length; i++)
|
||
{
|
||
int index = i;
|
||
|
||
if (HtL)
|
||
{
|
||
index = data.Length - 1 - i;
|
||
}
|
||
|
||
res += data[index] << (8 * i);
|
||
}
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取一个类指定的属性值
|
||
/// </summary>
|
||
/// <param name="info">object对象</param>
|
||
/// <param name="field">属性名称</param>
|
||
/// <returns></returns>
|
||
public static object GetPropertyValue(object info, string field)
|
||
{
|
||
if (info == null) return null;
|
||
Type t = info.GetType();
|
||
IEnumerable<System.Reflection.PropertyInfo> property = from pi in t.GetProperties() where pi.Name.ToLower() == field.ToLower() select pi;
|
||
return property.First().GetValue(info, null);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将32位整形拆分为无符号16位整形
|
||
/// </summary>
|
||
/// <param name="num">需要拆分的32位整形</param>
|
||
/// <param name="bitNum">拆分为16位整形的位数 1或者2</param>
|
||
/// <param name="HtL">true:高位在前,低位在后;false:高位在后,低位在前</param>
|
||
/// <returns></returns>
|
||
public static List<ushort> ParseIntToUnsignShortList(this int num, int bitNum = 2, bool HtL = false)
|
||
{
|
||
if (bitNum == 2)
|
||
{
|
||
ushort high = (ushort)(num >> 16);
|
||
ushort low = (ushort)num;
|
||
|
||
if (HtL)
|
||
{
|
||
return new List<ushort>() { high, low };
|
||
}
|
||
else
|
||
{
|
||
return new List<ushort>() { low, high };
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (num < 0)
|
||
{
|
||
num = ushort.MaxValue + 1 + num;
|
||
}
|
||
|
||
return new List<ushort>() { (ushort)num };
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将32位整形数组拆分为无符号16位整形数组
|
||
/// </summary>
|
||
/// <param name="list">需要拆分的32位整形</param>
|
||
/// <param name="bitNum">拆分为16位整形的位数 1或者2</param>
|
||
/// <param name="HtL">true:高位在前,低位在后;false:高位在后,低位在前</param>
|
||
/// <returns></returns>
|
||
public static List<ushort> ParseIntToUnsignShortList(this List<int> list, int bitNum = 2, bool HtL = false)
|
||
{
|
||
return list.SelectMany(u => u.ParseIntToUnsignShortList(bitNum, HtL)).ToList();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将ushort的集合转换为16位带符号整形
|
||
/// </summary>
|
||
/// <param name="numList"></param>
|
||
/// <param name="bitNum">合并的位数 1或者2</param>
|
||
/// <param name="HtL">true:高位在前,低位在后;false:高位在后,低位在前</param>
|
||
/// <returns></returns>
|
||
public static List<int> ParseUnsignShortListToInt(this List<int> numList, int bitNum = 2, bool HtL = false)
|
||
{
|
||
if (bitNum == 1)
|
||
{
|
||
return numList.ConvertAll(n =>
|
||
{
|
||
int num = n;
|
||
if (num > short.MaxValue)
|
||
{
|
||
num = num - ushort.MaxValue - 1;
|
||
}
|
||
|
||
return num;
|
||
});
|
||
}
|
||
else
|
||
{
|
||
List<int> list = new List<int>();
|
||
for (int i = 0; i < numList.Count; i += 2)
|
||
{
|
||
int high = HtL ? numList[i] : numList[i + 1];
|
||
int low = HtL ? numList[i + 1] : numList[i];
|
||
list.Add((high << 16) | low);
|
||
}
|
||
|
||
return list;
|
||
}
|
||
}
|
||
|
||
//public static T DeepSerializeClone<T>(this T t)
|
||
//{
|
||
// return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(t));
|
||
//}
|
||
|
||
public static void DataFrom<T1, T2>(this T1 destT, T2 sourceT, List<string> exceptionProps = null) where T1 : class where T2 : class
|
||
{
|
||
if (sourceT == null)
|
||
{
|
||
destT = null;
|
||
return;
|
||
}
|
||
|
||
PropertyInfo[] propDest = destT.GetType().GetProperties();//.Where(p => !(p.GetMethod.IsVirtual && !p.GetMethod.IsFinal)).ToArray();
|
||
PropertyInfo[] propSource = sourceT.GetType().GetProperties();
|
||
|
||
Array.ForEach(propDest, prop =>
|
||
{
|
||
if (exceptionProps == null || !exceptionProps.Contains(prop.Name))
|
||
{
|
||
if (prop.CanWrite)
|
||
{
|
||
PropertyInfo propS = propSource.FirstOrDefault(p => p.Name == prop.Name);
|
||
if (propS != null && propS.CanRead)
|
||
{
|
||
prop.SetValue(destT, propS.GetValue(sourceT));
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
public static Bitmap BitmapSerializeCopy(this Bitmap map)
|
||
{
|
||
Bitmap image = null;
|
||
using (MemoryStream ms = new MemoryStream())
|
||
{
|
||
BinaryFormatter bf = new BinaryFormatter();
|
||
#if NET7_0_OR_GREATER
|
||
#pragma warning disable SYSLIB0011
|
||
#endif
|
||
bf.Serialize(ms, map);
|
||
ms.Seek(0, SeekOrigin.Begin);
|
||
image = (Bitmap)bf.Deserialize(ms);
|
||
#if NET7_0_OR_GREATER
|
||
#pragma warning restore SYSLIB0011
|
||
#endif
|
||
//ms.Close();
|
||
}
|
||
|
||
return image;
|
||
}
|
||
|
||
public static Bitmap DeepClone(this Bitmap bitmap)
|
||
{
|
||
Bitmap dstBitmap = null;
|
||
using (MemoryStream mStream = new MemoryStream())
|
||
{
|
||
BinaryFormatter bf = new BinaryFormatter();
|
||
#if NET7_0_OR_GREATER
|
||
#pragma warning disable SYSLIB0011
|
||
#endif
|
||
bf.Serialize(mStream, bitmap);
|
||
//#pragma warning restore SYSLIB0011
|
||
mStream.Seek(0, SeekOrigin.Begin);
|
||
dstBitmap = (Bitmap)bf.Deserialize(mStream);
|
||
mStream.Close();
|
||
#if NET7_0_OR_GREATER
|
||
#pragma warning restore SYSLIB0011
|
||
#endif
|
||
}
|
||
return dstBitmap;
|
||
}
|
||
//RtlMoveMemory
|
||
[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
|
||
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
|
||
[HandleProcessCorruptedStateExceptions]
|
||
public static Bitmap CopyBitmap(this Bitmap source)
|
||
{
|
||
Bitmap clone = new Bitmap(source.Width, source.Height, source.PixelFormat);
|
||
try
|
||
{
|
||
int PixelSize = Bitmap.GetPixelFormatSize(source.PixelFormat) / 8;
|
||
if (PixelSize == 1)
|
||
{
|
||
ColorPalette cp = clone.Palette;
|
||
for (int i = 0; i < 256; i++)
|
||
{
|
||
cp.Entries[i] = Color.FromArgb(255, i, i, i);
|
||
}
|
||
clone.Palette = cp;
|
||
}
|
||
|
||
Rectangle rect = new Rectangle(0, 0, source.Width, source.Height);
|
||
BitmapData sourceData = source.LockBits(rect, ImageLockMode.ReadWrite, source.PixelFormat);
|
||
BitmapData cloneData = clone.LockBits(rect, ImageLockMode.ReadWrite, source.PixelFormat);
|
||
if (source.Width % 4 == 0)
|
||
{
|
||
unsafe
|
||
{
|
||
CopyMemory(cloneData.Scan0, sourceData.Scan0, (uint)(sourceData.Stride * sourceData.Height));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Parallel.For(0, source.Height, h =>
|
||
{
|
||
unsafe
|
||
{
|
||
CopyMemory(cloneData.Scan0 + h * sourceData.Stride, sourceData.Scan0 + h * sourceData.Stride, (uint)sourceData.Width);
|
||
}
|
||
});
|
||
}
|
||
|
||
clone.UnlockBits(cloneData);
|
||
source.UnlockBits(sourceData);
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return clone;
|
||
}
|
||
|
||
return clone;
|
||
}
|
||
|
||
public static Bitmap BitmapDeepClone(Bitmap source)
|
||
{
|
||
Bitmap clone = new Bitmap(source.Width, source.Height, source.PixelFormat);
|
||
|
||
try
|
||
{
|
||
int PixelSize = Bitmap.GetPixelFormatSize(source.PixelFormat) / 8;
|
||
if (PixelSize == 1)
|
||
{
|
||
ColorPalette cp = clone.Palette;
|
||
for (int i = 0; i < 256; i++)
|
||
{
|
||
cp.Entries[i] = Color.FromArgb(255, i, i, i);
|
||
}
|
||
clone.Palette = cp;
|
||
}
|
||
Rectangle rect = new Rectangle(0, 0, source.Width, source.Height);
|
||
BitmapData source_bitmap = source.LockBits(rect, ImageLockMode.ReadWrite, source.PixelFormat);
|
||
BitmapData destination_bitmap = clone.LockBits(rect, ImageLockMode.ReadWrite, clone.PixelFormat);
|
||
|
||
int depth_width = source_bitmap.Width * PixelSize;
|
||
|
||
unsafe
|
||
{
|
||
byte* source_ptr = (byte*)source_bitmap.Scan0;
|
||
byte* destination_ptr = (byte*)destination_bitmap.Scan0;
|
||
|
||
int offset = source_bitmap.Stride - depth_width;
|
||
|
||
for (int i = 0; i < source_bitmap.Height; i++)
|
||
{
|
||
for (int j = 0; j < depth_width; j++, source_ptr++, destination_ptr++)
|
||
{
|
||
*destination_ptr = *source_ptr;
|
||
}
|
||
|
||
source_ptr += offset;
|
||
destination_ptr += offset;
|
||
}
|
||
}
|
||
|
||
source.UnlockBits(source_bitmap);
|
||
clone.UnlockBits(destination_bitmap);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
|
||
}
|
||
return clone;
|
||
}
|
||
|
||
|
||
|
||
public static Bitmap HConnectBitmap(this Bitmap map1, Bitmap map2)
|
||
{
|
||
Bitmap connectImage = null;
|
||
if (map1 == null || map2 == null)
|
||
return null;
|
||
//横向拼接
|
||
int width = map1.Width + map2.Width;
|
||
//高度不变
|
||
int height = Math.Max(map1.Height, map2.Height);
|
||
connectImage = new Bitmap(width, height);
|
||
using (Graphics graph = Graphics.FromImage(connectImage))
|
||
{
|
||
graph.DrawImage(connectImage, width, height);
|
||
graph.Clear(System.Drawing.Color.White);
|
||
graph.DrawImage(map1, 0, 0);
|
||
graph.DrawImage(map2, map1.Width, 0);
|
||
}
|
||
return connectImage;
|
||
}
|
||
|
||
public static IntPtr FloatToIntptr(float[] bytes)
|
||
{
|
||
GCHandle hObject = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||
return hObject.AddrOfPinnedObject();
|
||
}
|
||
|
||
// 将Btimap类转换为byte[]类函数
|
||
public static byte[] GetBGRValues(Bitmap bmp, out int stride)
|
||
{
|
||
var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
|
||
var bmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat);
|
||
stride = bmpData.Stride;
|
||
var rowBytes = bmpData.Width * Image.GetPixelFormatSize(bmp.PixelFormat) / 8;
|
||
var imgBytes = bmp.Height * rowBytes;
|
||
byte[] rgbValues = new byte[imgBytes];
|
||
IntPtr ptr = bmpData.Scan0;
|
||
for (var i = 0; i < bmp.Height; i++)
|
||
{
|
||
Marshal.Copy(ptr, rgbValues, i * rowBytes, rowBytes);
|
||
ptr += bmpData.Stride;
|
||
}
|
||
bmp.UnlockBits(bmpData);
|
||
return rgbValues;
|
||
}
|
||
/// <summary>
|
||
/// 缺陷灰度图转彩色图像函数
|
||
/// </summary>
|
||
/// <param name="src">灰度图</param>
|
||
/// <returns>返回构造的伪彩色图像</returns>
|
||
public static Bitmap GrayMapToColorMap(this Bitmap src, Dictionary<int, Color> indexColorDict = null)
|
||
{
|
||
try
|
||
{
|
||
//Stopwatch sw = new Stopwatch();
|
||
//sw.Start();
|
||
|
||
Bitmap dest = new Bitmap(src.Width, src.Height, PixelFormat.Format32bppArgb);
|
||
|
||
int destHeight = dest.Height;
|
||
int destWidth = dest.Width;
|
||
|
||
Rectangle rect = new Rectangle(0, 0, destWidth, destHeight);
|
||
BitmapData bmpDataDest = dest.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
||
BitmapData bmpDataSrc = src.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
|
||
int strideDest = bmpDataDest.Stride;
|
||
|
||
int strideSrc = bmpDataSrc.Stride;
|
||
unsafe
|
||
{
|
||
byte* pDest = (byte*)bmpDataDest.Scan0.ToPointer();
|
||
byte* pSrc = (byte*)bmpDataSrc.Scan0.ToPointer();
|
||
|
||
Parallel.For(0, destHeight, y =>
|
||
{
|
||
Parallel.For(0, destWidth, x =>
|
||
{
|
||
int pixel = pSrc[y * strideSrc + x];
|
||
int startIndex = y * strideDest + x * 4;
|
||
if (pixel >= 0 && pixel <= 63)
|
||
{
|
||
Color color = Color.Red;
|
||
if (indexColorDict != null && indexColorDict.ContainsKey(pixel))
|
||
{
|
||
color = indexColorDict[pixel];
|
||
}
|
||
|
||
byte R = color.R;
|
||
byte G = color.G;
|
||
byte B = color.B;
|
||
|
||
pDest[startIndex] = B;
|
||
pDest[startIndex + 1] = G;
|
||
pDest[startIndex + 2] = R;
|
||
pDest[startIndex + 3] = 100;
|
||
}
|
||
else
|
||
{
|
||
pDest[startIndex] = 255;
|
||
pDest[startIndex + 1] = 255;
|
||
pDest[startIndex + 2] = 255;
|
||
pDest[startIndex + 3] = 0;
|
||
}
|
||
});
|
||
});
|
||
}
|
||
dest.UnlockBits(bmpDataDest);
|
||
src.UnlockBits(bmpDataSrc);
|
||
|
||
//sw.Stop();
|
||
//Console.WriteLine($"转换耗时:{sw.ElapsedMilliseconds}");
|
||
|
||
return dest;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return null;
|
||
}
|
||
}
|
||
|
||
public static void Sort<T>(this ObservableCollection<T> collection) where T : IComparable<T>
|
||
{
|
||
List<T> sortedList = collection.OrderByDescending(x => x).ToList();//这里用降序
|
||
for (int i = 0; i < sortedList.Count(); i++)
|
||
{
|
||
collection.Move(collection.IndexOf(sortedList[i]), i);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获得字符串中开始和结束字符串中间的值
|
||
/// </summary>
|
||
/// <param name="sourse"></param>
|
||
/// <param name="startstr"></param>
|
||
/// <param name="endstr"></param>
|
||
/// <returns></returns>
|
||
public static string GetMidString(string sourse, string startstr, string endstr)
|
||
{
|
||
string result = string.Empty;
|
||
int startindex, endindex;
|
||
try
|
||
{
|
||
startindex = sourse.IndexOf(startstr);
|
||
if (startindex == -1)
|
||
return result;
|
||
string tmpstr = sourse.Substring(startindex + startstr.Length);
|
||
endindex = tmpstr.IndexOf(endstr);
|
||
if (endindex == -1)
|
||
return result;
|
||
result = tmpstr.Remove(endindex);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return "";
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获得字符串中开始和结束字符串中间的值
|
||
/// </summary>
|
||
/// <param name="t">字符串</param>
|
||
/// <param name="k">开始</param>
|
||
/// <param name="j">结束</param>
|
||
/// <returns></returns>
|
||
private static string GetMidString2(string sourse, string startstr, string endstr) //截取指定文本,和易语言的取文本中间差不多
|
||
{
|
||
try //异常捕捉
|
||
{
|
||
var kn = sourse.IndexOf(startstr, StringComparison.Ordinal) + startstr.Length;
|
||
var jn = sourse.IndexOf(endstr, kn, StringComparison.Ordinal);
|
||
return sourse.Substring(kn, jn - kn);
|
||
}
|
||
catch //如果发现未知的错误,比如上面的代码出错了,就执行下面这句代码
|
||
{
|
||
return ""; //返回空
|
||
}
|
||
|
||
}
|
||
|
||
// 布尔类型转换为整型
|
||
public static int ToInt(this object obj)
|
||
{
|
||
if (Convert.ToBoolean(obj) == true)
|
||
return 1;
|
||
else
|
||
return 0;
|
||
}
|
||
|
||
// 整型转换为布尔类型
|
||
public static bool ToBool(this object obj)
|
||
{
|
||
if (Convert.ToInt32(obj) == 1)
|
||
return true;
|
||
else
|
||
return false;
|
||
}
|
||
|
||
public static object GetProperty(this object o, string member)
|
||
{
|
||
if (o == null) throw new ArgumentNullException("o");
|
||
if (member == null) throw new ArgumentNullException("member");
|
||
Type scope = o.GetType();
|
||
IDynamicMetaObjectProvider provider = o as IDynamicMetaObjectProvider;
|
||
if (provider != null)
|
||
{
|
||
ParameterExpression param = Expression.Parameter(typeof(object));
|
||
DynamicMetaObject mobj = provider.GetMetaObject(param);
|
||
GetMemberBinder binder = (GetMemberBinder)Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, member, scope, new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(0, null) });
|
||
DynamicMetaObject ret = mobj.BindGetMember(binder);
|
||
BlockExpression final = Expression.Block(
|
||
Expression.Label(CallSiteBinder.UpdateLabel),
|
||
ret.Expression
|
||
);
|
||
LambdaExpression lambda = Expression.Lambda(final, param);
|
||
Delegate del = lambda.Compile();
|
||
return del.DynamicInvoke(o);
|
||
}
|
||
else
|
||
{
|
||
return o.GetType().GetProperty(member, BindingFlags.Public | BindingFlags.Instance).GetValue(o, null);
|
||
}
|
||
}
|
||
|
||
#region 检测文件状态及操作方式选择
|
||
[DllImport("kernel32.dll")]
|
||
private static extern IntPtr _lopen(string lpPathName, int iReadWrite);
|
||
[DllImport("kernel32.dll")]
|
||
private static extern bool CloseHandle(IntPtr hObject);
|
||
private const int OF_READWRITE = 2;
|
||
private const int OF_SHARE_DENY_NONE = 0x40;
|
||
private static readonly IntPtr HFILE_ERROR = new IntPtr(-1);
|
||
/// <summary>
|
||
/// 检测文件是否只读或被使用
|
||
/// </summary>
|
||
/// <param name="FileNames">要检测的文件</param>
|
||
/// <returns>true可用,false在用或只读</returns>
|
||
public static bool CheckFilesCanUse(string fileName)
|
||
{
|
||
if (!File.Exists(fileName))
|
||
return true;//文件不存在
|
||
if ((File.GetAttributes(fileName) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
|
||
return false; //文件只读
|
||
IntPtr vHandle = _lopen(fileName, OF_READWRITE | OF_SHARE_DENY_NONE);
|
||
if (vHandle == HFILE_ERROR)
|
||
{
|
||
CloseHandle(vHandle);
|
||
return false; //文件被占用
|
||
}
|
||
|
||
CloseHandle(vHandle); //文件没被占用
|
||
return true;
|
||
}
|
||
#endregion
|
||
|
||
/// <summary>
|
||
/// 获取指定文件夹下所有的文件名称
|
||
/// </summary>
|
||
/// <param name="folderName">指定文件夹名称,绝对路径</param>
|
||
/// <param name="fileFilter">文件类型过滤,根据文件后缀名,如:*,*.txt,*.xls</param>
|
||
/// <param name="isContainSubFolder">是否包含子文件夹</param>
|
||
/// <returns>ArrayList数组,为所有需要的文件路径名称</returns>
|
||
public static List<FileInfo> GetAllFilesByFolder(string folderName, string fileFilter, bool isContainSubFolder = false)
|
||
{
|
||
List<FileInfo> resList = new List<FileInfo>();
|
||
try
|
||
{
|
||
DirectoryInfo currDir = new DirectoryInfo(folderName);//当前目录
|
||
FileInfo[] currFiles = currDir.GetFiles(fileFilter);//当前目录文件
|
||
foreach (FileInfo file in currFiles)
|
||
{
|
||
if (fileFilter.ToLower().IndexOf(file.Extension.ToLower()) >= 0)
|
||
{
|
||
resList.Add(file);
|
||
}
|
||
}
|
||
if (isContainSubFolder)
|
||
{
|
||
string[] subFolders = Directory.GetDirectories(folderName);
|
||
foreach (string subFolder in subFolders)
|
||
{
|
||
resList.AddRange(GetAllFilesByFolder(subFolder, fileFilter));//递归
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
throw ex;
|
||
}
|
||
return resList;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取指定文件夹下所有的文件名称,不过滤文件类型
|
||
/// </summary>
|
||
/// <param name="folderName">指定文件夹名称,绝对路径</param>
|
||
/// <param name="isContainSubFolder">是否包含子文件夹</param>
|
||
/// <returns>ArrayList数组,为所有需要的文件路径名称</returns>
|
||
public static List<FileInfo> GetAllFilesByFolder(string folderName, bool isContainSubFolder)
|
||
{
|
||
return GetAllFilesByFolder(folderName, "*", isContainSubFolder);
|
||
}
|
||
}
|
||
|
||
public class Compare<T, C> : IEqualityComparer<T>
|
||
{
|
||
private Func<T, C> _getField;
|
||
public Compare(Func<T, C> getfield)
|
||
{
|
||
_getField = getfield;
|
||
}
|
||
public bool Equals(T x, T y)
|
||
{
|
||
return EqualityComparer<C>.Default.Equals(_getField(x), _getField(y));
|
||
}
|
||
public int GetHashCode(T obj)
|
||
{
|
||
return EqualityComparer<C>.Default.GetHashCode(_getField(obj));
|
||
}
|
||
}
|
||
|
||
public static class ObjectExtensions
|
||
{
|
||
public static IEnumerable<T> DistinctBy<T, C>(this IEnumerable<T> source, Func<T, C> getfield)
|
||
{
|
||
return source.Distinct(new Compare<T, C>(getfield));
|
||
}
|
||
|
||
public static IQueryable<T> DistinctBy<T, C>(this IQueryable<T> source, Func<T, C> getfield)
|
||
{
|
||
return source.Distinct(new Compare<T, C>(getfield));
|
||
}
|
||
}
|
||
|