[성현모] CPXV2 Init

This commit is contained in:
SHM
2024-06-26 10:30:00 +09:00
parent cdf12248c5
commit 5958993b6a
588 changed files with 698420 additions and 0 deletions

View File

@ -0,0 +1,153 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace SystemX.Net.Platform.Common.ExtensionMethods
{
public static class EmAsync
{
public static TResult WaitResultAsyncFunction<TResult>(this Func<Task<TResult>> function)
{
var task = Task.Run(() => function());
task.Wait();
return task.Result;
}
public static void WaitAsyncFunction(this Func<Task> function)
{
function().Wait();
}
//private static Action WrapExceptionSafe(this Action action, Action<Exception> exceptionHandler)
//{
// return new Action(() =>
// {
// try
// {
// action();
// }
// catch (Exception ex)
// {
// if (exceptionHandler == null)
// {
// if ( FormAppCommon.UISynchronizationContext == null )
// MessageBox.Show(ex.Message, "Exception occurred!", MessageBoxButtons.OK, MessageBoxIcon.Error);
// else
// FormAppCommon.UISynchronizationContext.Send(ignore => UnhandledExceptionHandler.ShowUnhandledException(ex), null);
// }
// else
// exceptionHandler(ex);
// }
// });
//}
//public static Func<Task<T>> WrapExceptionSafe<T>(this Func<Task<T>> function, Action<Exception> exceptionHandler)
//{
// return new Func<Task<T>>(() =>
// {
// try
// {
// return function();
// }
// catch (Exception ex)
// {
// if (exceptionHandler == null)
// {
// if (FormAppCommon.UISynchronizationContext == null)
// MessageBox.Show(ex.Message, "Exception occurred!", MessageBoxButtons.OK, MessageBoxIcon.Error);
// else
// FormAppCommon.UISynchronizationContext.Send(ignore => UnhandledExceptionHandler.ShowUnhandledException(ex), null);
// }
// else
// exceptionHandler(ex);
// return null;
// }
// });
//}
///// <summary>
///// 단순히 Task.Run(()=>{}) 수행시, exception 을 catch 할수 없으므로, 다음 extension 을 사용해서 해결함
///// </summary>
///// <param name="action"></param>
///// <param name="exceptionHandler"></param>
//public static Task ExceptionSafeTaskRun(this Action action, Action<Exception> exceptionHandler=null)
//{
// return Task.Run(WrapExceptionSafe(action, exceptionHandler));
//}
//public static Task<T> ExceptionSafeTaskRun<T>(this Func<Task<T>> function, Action<Exception> exceptionHandler=null)
//{
// return Task.Run(WrapExceptionSafe(function, exceptionHandler));
//}
//private static void HandleException(this Task task)
//{
// var ex = task.Exception;
// if (ex != null)
// {
// System.Diagnostics.Trace.WriteLine(ex.ToString());
// Globals.Logger?.Error(ex.ToString());
// }
//}
///// <summary>
///// Disabling CS4014
///// http://stackoverflow.com/questions/22629951/suppressing-warning-cs4014-because-this-call-is-not-awaited-execution-of-the
///// warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed.
///// Consider applying the 'await' operator to the result of the call.
///// </summary>
///// <param name="task"></param>
//public static void Forget(this Task task)
//{
// // Async in C# 5.0, pp.57
// // Task 를 실행만 하고, await 하지 않는 fire & forget 모델에서, exception 이 발생하였을 경우를 체크 하기 위한 용도.
// task.ContinueWith(ant => HandleException(ant));
//}
/// <summary>
/// http://stackoverflow.com/questions/2565166/net-best-way-to-execute-a-lambda-on-ui-thread-after-a-delay
/// </summary>
/// Usage
/// <code>
/// SynchronizationContext.Current.Post(TimeSpan.FromSeconds(1), () => textBlock.Text="Done");
/// </code>
public static void Post(this SynchronizationContext context, TimeSpan delay, Action action)
{
System.Threading.Timer timer = null;
timer = new System.Threading.Timer((ignore) =>
{
timer.Dispose();
context.Post(ignore2 => action(), null);
}, null, delay, TimeSpan.FromMilliseconds(-1));
}
/// <summary>
/// Executes action after delay.
/// C# 5.0 in a Nutshell, pp. 573
/// </summary>
/// <param name="action"></param>
/// <param name="delayMillisec"></param>
/// <returns></returns>
public static Task ExecuteWithDelay(this Action action, int delayMillisec)
{
return Task.Delay(delayMillisec).ContinueWith(ant => action);
}
/// <summary>
/// pp.20. Concurrency in C# Cookbook
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public static Task<T> FromResult<T>(this T value)
{
return Task.FromResult(value);
}
}
}

View File

@ -0,0 +1,161 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace SystemX.Net.Platform.Common.ExtensionMethods
{
/// <summary>
///
/// </summary>
/// http://stackoverflow.com/questions/2368757/easy-way-to-convert-a-bitmap-and-png-image-to-text-and-vice-versa
/// http://www.developerfusion.com/thread/47978/how-can-i-convert-image-type-to-bitmap-type-in-cnet/
/// http://stackoverflow.com/questions/10442269/scaling-a-system-drawing-bitmap-to-a-given-size-while-maintaining-aspect-ratio
public static class EmBitmap
{
public static string EncodeToString(this Bitmap bitmap)
{
if ( bitmap == null )
return String.Empty;
MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Png);
byte[] bitmapBytes = memoryStream.GetBuffer();
return Convert.ToBase64String(bitmapBytes, Base64FormattingOptions.InsertLineBreaks);
}
public static Bitmap FromEncodedString(string bitmapString)
{
byte[] bitmapBytes = Convert.FromBase64String(bitmapString);
MemoryStream memoryStream = new MemoryStream(bitmapBytes);
return new Bitmap(Image.FromStream(memoryStream));
}
public static Bitmap Resize(this Bitmap bitmap, int width)
{
double height = width * ((double)bitmap.Height / bitmap.Width);
return new Bitmap(bitmap, new Size(width, (int)height));
}
public static Icon ToIcon(this Bitmap bitmap)
{
return Icon.FromHandle(bitmap.GetHicon());
}
public static Bitmap ToBitmap(this Image image)
{
return (Bitmap) image;
}
public static Icon ToIcon(this Image image)
{
return Icon.FromHandle(((Bitmap)image).GetHicon());
}
}
public class ImageHelper
{
#region CropUnwantedBackground
public static Bitmap CropUnwantedBackground(Bitmap bmp)
{
var backColor = GetMatchedBackColor(bmp);
if (backColor.HasValue)
{
var bounds = GetImageBounds(bmp, backColor);
var diffX = bounds[1].X - bounds[0].X + 1;
var diffY = bounds[1].Y - bounds[0].Y + 1;
var croppedBmp = new Bitmap(diffX, diffY);
var g = Graphics.FromImage(croppedBmp);
var destRect = new Rectangle(0, 0, croppedBmp.Width, croppedBmp.Height);
var srcRect = new Rectangle(bounds[0].X, bounds[0].Y, diffX, diffY);
g.DrawImage(bmp, destRect, srcRect, GraphicsUnit.Pixel);
return croppedBmp;
}
else
{
return null;
}
}
#endregion
#region Private Methods
#region GetImageBounds
private static Point[] GetImageBounds(Bitmap bmp, Color? backColor)
{
//--------------------------------------------------------------------
// Finding the Bounds of Crop Area bu using Unsafe Code and Image Proccesing
Color c;
int width = bmp.Width, height = bmp.Height;
bool upperLeftPointFounded = false;
var bounds = new Point[2];
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
c = bmp.GetPixel(x, y);
bool sameAsBackColor = ((c.R <= backColor.Value.R * 1.1 && c.R >= backColor.Value.R * 0.9) &&
(c.G <= backColor.Value.G * 1.1 && c.G >= backColor.Value.G * 0.9) &&
(c.B <= backColor.Value.B * 1.1 && c.B >= backColor.Value.B * 0.9));
if (!sameAsBackColor)
{
if (!upperLeftPointFounded)
{
bounds[0] = new Point(x, y);
bounds[1] = new Point(x, y);
upperLeftPointFounded = true;
}
else
{
if (x > bounds[1].X)
bounds[1].X = x;
else if (x < bounds[0].X)
bounds[0].X = x;
if (y >= bounds[1].Y)
bounds[1].Y = y;
}
}
}
}
return bounds;
}
#endregion
#region GetMatchedBackColor
private static Color? GetMatchedBackColor(Bitmap bmp)
{
// Getting The Background Color by checking Corners of Original Image
var corners = new Point[]{
new Point(0, 0),
new Point(0, bmp.Height - 1),
new Point(bmp.Width - 1, 0),
new Point(bmp.Width - 1, bmp.Height - 1)
}; // four corners (Top, Left), (Top, Right), (Bottom, Left), (Bottom, Right)
for (int i = 0; i < 4; i++)
{
var cornerMatched = 0;
var backColor = bmp.GetPixel(corners[i].X, corners[i].Y);
for (int j = 0; j < 4; j++)
{
var cornerColor = bmp.GetPixel(corners[j].X, corners[j].Y);// Check RGB with some offset
if ((cornerColor.R <= backColor.R * 1.1 && cornerColor.R >= backColor.R * 0.9) &&
(cornerColor.G <= backColor.G * 1.1 && cornerColor.G >= backColor.G * 0.9) &&
(cornerColor.B <= backColor.B * 1.1 && cornerColor.B >= backColor.B * 0.9))
{
cornerMatched++;
}
}
if (cornerMatched > 2)
{
return backColor;
}
}
return null;
}
#endregion
#endregion
}
}

View File

@ -0,0 +1,75 @@
using System;
using System.Diagnostics.Contracts;
using System.Linq;
namespace SystemX.Net.Platform.Common.ExtensionMethods
{
public static class EmComparable
{
/// <summary>
/// [min, max]
/// value 값이 from, to 사이에 존재하는지를 검사한다.
/// http://stackoverflow.com/questions/8776624/if-value-in-rangex-y-function-c-sharp
/// </summary>
[Pure]
public static bool InClosedRange<T>(this T val, T min, T max) where T : IComparable<T>
{
Contract.Requires(min.CompareTo(max) <= 0);
return min.CompareTo(val) <= 0 && val.CompareTo(max) <= 0;
}
[Pure]
public static bool InRange<T>(this T val, T min, T max) where T : IComparable<T>
{
return val.InClosedRange(min, max);
}
/// <summary> [min, max) </summary>
[Pure]
public static bool InClampRange<T>(this T val, T min, T max) where T : IComparable<T>
{
Contract.Requires(min.CompareTo(max) <= 0);
return min.CompareTo(val) <= 0 && val.CompareTo(max) < 0;
}
/// <summary> (min, max) </summary>
[Pure]
public static bool InOpenRange<T>(this T val, T min, T max) where T : IComparable<T>
{
Contract.Requires(min.CompareTo(max) <= 0);
return min.CompareTo(val) < 0 && val.CompareTo(max) < 0;
}
[Pure]
public static bool EpsilonEqual(this double value1, double value2, double epsilon = Double.Epsilon)
{
return Math.Abs(value1 - value2) < epsilon;
}
[Pure]
public static bool EpsilonEqual(this float value1, float value2, float epsilon = Single.Epsilon)
{
return Math.Abs(value1 - value2) < epsilon;
}
/// <summary> Key 값이 set 에 포함되는지 여부를 검사한다. </summary>
[Pure]
public static bool IsOneOf(this IComparable key, params IComparable[] set)
{
return set.Any(e => e.CompareTo(key) == 0);
}
public static bool IsOneOf(this object key, params object[] set)
{
return set.Any(e => e == key);
}
public static bool IsOneOf(this Type type, params Type[] set)
{
return set.Any(t => t.IsAssignableFrom(type));
}
}
}

View File

@ -0,0 +1,427 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace SystemX.Net.Platform.Common.ExtensionMethods
{
/// <summary>
/// http://lostechies.com/derickbailey/2011/01/24/asynchronous-control-updates-in-c-net-winforms/
/// </summary>
public static class EmControl
{
public static void Do<TControl>(this TControl control, Action<TControl> action)
where TControl : Control
{
try
{
if (control.InvokeRequired)
{
try
{
control.Invoke(action, control);
}
catch (Exception ex)
{
if (ex is ObjectDisposedException)
Trace.WriteLine(ex);
else
throw;
}
}
else if (control.IsHandleCreated)
action(control);
else
{
Console.WriteLine("Error : Before windows handle created.. 창 핸들을 만들기 전까지는....");
Trace.WriteLine("Error : Before windows handle created.. 창 핸들을 만들기 전까지는....");
}
}
catch (Exception ex)
{
Trace.WriteLine($"Exception on Control.Do(): {ex}");
}
}
/// <summary>
/// Control.Invoke is synchronous
/// </summary>
/// <param name="control"></param>
/// <param name="action"></param>
public static void Do(this Control control, Action action)
{
try
{
if (control.InvokeRequired)
{
try
{
control.Invoke(action);
}
catch (Exception ex)
{
if (ex is ObjectDisposedException)
Trace.WriteLine(ex);
else
throw;
}
}
else if (control.IsHandleCreated)
action();
else
{
Console.WriteLine("Error : Before windows handle created (2).. 창 핸들을 만들기 전까지는....");
Trace.WriteLine("Error : Before windows handle created (2).. 창 핸들을 만들기 전까지는....");
}
}
catch (Exception ex)
{
Trace.WriteLine($"Exception on Control.Do(): {ex}");
}
}
public static void Do(this SynchronizationContext context, Action action)
{
context.Send(ignore => { action(); }, null);
}
public static void DoAsync(this SynchronizationContext context, Action action)
{
context.Post(ignore => { action(); }, null);
}
public static SynchronizationContext GetSynchronizationContext(this Control control)
{
SynchronizationContext context = null;
control.Do(() =>
{
context = SynchronizationContext.Current;
});
return context;
}
public static TaskScheduler GetTaskScheduler(this Control control)
{
TaskScheduler scheduler = null;
control.Do(() =>
{
scheduler = TaskScheduler.FromCurrentSynchronizationContext();
});
return scheduler;
}
/// <summary>
/// form 에 대해서, 아직 창 핸들이 만들어 지지 않은 경우, form 이 보여진 후에 해당 action 을 수행한다.
/// </summary>
/// <param name="form"></param>
/// <param name="action"></param>
public static void DoNowOrLater(this Form form, Action action)
{
if (form.InvokeRequired)
form.Invoke(action);
else if (form.IsHandleCreated)
action();
else
form.Shown += (sender, args) => { action(); };
}
public static async Task DoAsync(this Control control, Action action)
{
try
{
if (control.InvokeRequired)
await Task.Factory.FromAsync(control.BeginInvoke(action), result => { });
else if (control.IsHandleCreated)
action();
else
Console.WriteLine("Error : 창 핸들을 만들기 전까지는....");
}
catch (Exception ex)
{
Trace.WriteLine($"Exception on Control.Do(): {ex}");
}
}
/// <summary>
/// How to get return value when BeginInvoke/Invoke is called in C#
/// http://stackoverflow.com/questions/2214002/how-to-get-return-value-when-begininvoke-invoke-is-called-in-c-sharp
/// </summary>
public static T DoGet<T>(this Control control, Func<T> func)
{
if (control.InvokeRequired)
return (T)control.Invoke(func);
return func();
}
public static IEnumerable<Control> CollectAncestors(this Control control, bool includeMe = false)
{
if (includeMe)
yield return control;
if (control == null || control.Parent == null)
yield break;
foreach (var ancestor in control.Parent.CollectAncestors(true))
yield return ancestor;
}
public static IEnumerable<Control> CollectAncestorsTo(this Control control, Control stopAncestorControl,
bool includeMe = false)
{
if (includeMe)
yield return control;
if (control == stopAncestorControl || control.Parent == null)
yield break;
foreach (var ancestor in control.Parent.CollectAncestorsTo(stopAncestorControl, true))
yield return ancestor;
}
public static IEnumerable<Control> CollectChildren(this Control control, bool includeMe = false)
{
if (includeMe)
yield return control;
foreach (var child in control.Controls.Cast<Control>())
{
foreach (var descendant in child.CollectChildren(true))
yield return descendant;
}
if (control is TabControl)
{
var tab = (TabControl) control;
foreach (var page in tab.TabPages.Cast<TabPage>())
{
foreach (var descendant in page.CollectChildren(true))
{
yield return descendant;
}
}
}
}
public static IEnumerable<T> CollectChildren<T>(this Control control, bool includeMe = false) where T : Control
{
return control.CollectChildren(includeMe).OfType<T>();
//if (includeMe && control is T)
// yield return control as T;
//foreach (var child in control.Controls.Cast<Control>())
//{
// foreach (var descendant in child.CollectChildren<T>(true))
// yield return descendant;
//}
//if (control is TabControl)
//{
// var tab = (TabControl)control;
// foreach (var page in tab.TabPages.Cast<TabPage>())
// {
// foreach (var descendant in page.CollectChildren<T>(true))
// {
// yield return descendant;
// }
// }
//}
}
/// <summary>
/// reference 의 LT 좌표 기준으로, control 의 LT 좌표의 offset 값을 반환한다.
/// </summary>
/// <param name="control"></param>
/// <param name="reference"></param>
/// <returns></returns>
public static Point GetRelativePoint(this Control control, Control reference)
{
return reference.PointToClient(control.PointToScreen(control.Location));
}
public static Rectangle GetRelativeRectangle(this Control control, Control reference)
{
return reference.RectangleToClient(control.RectangleToScreen(control.ClientRectangle));
}
public static void SetBackgroundImage(this Control control, Image image)
{
if (control.BackgroundImage != null)
control.BackgroundImage.Dispose();
control.BackgroundImage = image;
}
public static void MakeTransparent(this Control control)
{
try
{
if (control is Button)
((Button) control).FlatStyle = FlatStyle.Flat;
control.ForceMakeTransparent();
control.BackColor = Color.Transparent;
}
catch (Exception)
{
}
}
/// <summary>
/// http://solvedstack.com/questions/transparency-for-windows-forms-textbox
/// <c>
/// bool itWorked = SetStyle(xControl, ControlStyles.SupportsTransparentBackColor, true);
/// </c>
/// </summary>
/// <param name="control"></param>
/// <param name="style"></param>
/// <param name="value"></param>
/// <returns></returns>
public static bool ForceSetStyle(this Control control, ControlStyles style, bool value)
{
Type typeTB = typeof (Control);
System.Reflection.MethodInfo misSetStyle = typeTB.GetMethod("SetStyle",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (misSetStyle != null && control != null)
{
misSetStyle.Invoke(control, new object[] {style, value});
return true;
}
return false;
}
public static bool ForceMakeTransparent(this Control control, bool transparent = true)
{
return control.ForceSetStyle(ControlStyles.SupportsTransparentBackColor, transparent);
}
/// <summary>
/// http://stackoverflow.com/questions/435433/what-is-the-preferred-way-to-find-focused-control-in-winforms-app
/// </summary>
/// <param name="control"></param>
/// <returns></returns>
public static Control FindFocusedControl(this Control control)
{
var container = control as IContainerControl;
while (container != null)
{
control = container.ActiveControl;
container = control as IContainerControl;
}
return control;
}
// http://stackoverflow.com/questions/4747935/c-sharp-winform-check-if-control-is-physicaly-visible
[DllImport("user32.dll")]
static extern IntPtr WindowFromPoint(POINT Point);
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public POINT(int x, int y) { X = x; Y = y; }
public static implicit operator Point(POINT p) => new Point(p.X, p.Y);
public static implicit operator POINT(Point p) => new POINT(p.X, p.Y);
}
/// control 이 실제로 사용자에게 보이는지 여부를 반환
public static bool IsControlVisibleToUser(this Control control)
{
return control.DoGet(() =>
{
if (!control.IsHandleCreated)
return false;
var pos = control.PointToScreen(control.Location);
var pointsToCheck = new POINT[] {
pos,
new Point(pos.X + control.Width - 1, pos.Y),
new Point(pos.X, pos.Y + control.Height - 1),
new Point(pos.X + control.Width - 1, pos.Y + control.Height - 1),
new Point(pos.X + control.Width/2, pos.Y + control.Height/2),
};
foreach (var p in pointsToCheck)
{
var hwnd = WindowFromPoint(p);
var other = Control.FromChildHandle(hwnd);
if (other == null)
continue;
if (control == other || control.Contains(other))
return true;
}
return false;
});
}
#region Detect cursor
//// http://stackoverflow.com/questions/586479/is-there-a-quick-way-to-get-the-control-thats-under-the-mouse
//[DllImport("user32.dll")]
//private static extern IntPtr WindowFromPoint(Point pnt);
//public static Control ControlUnderPoint(this Point pt)
//{
// IntPtr hWnd = WindowFromPoint(pt);
// if (hWnd != IntPtr.Zero)
// return Control.FromHandle(hWnd);
// return null;
//}
//public static Control ControlUnderMouseCursor()
//{
// return Control.MousePosition.ControlUnderPoint();
//}
/// <summary> Checks whether mouse is over given control </summary>
public static bool IsMouseOver(this Control control)
{
return control.ClientRectangle.Contains(control.PointToClient(Cursor.Position));
}
/// <summary> Collects controls under mouse cursor </summary>
public static IEnumerable<Control> GetChildrenUnderMouse(this Control parent)
{
foreach (var c in parent.Controls.Cast<Control>())
{
if (c.IsMouseOver())
yield return c;
foreach (var cc in GetChildrenUnderMouse(c))
yield return cc;
}
}
#endregion
/// Button 에 image 를 입힌다. text 는 왼쪽, image 는 오른쪽
public static void AddImage(this Button button, Image image)
{
button.Image = image;
button.ImageAlign = ContentAlignment.MiddleRight;
button.TextAlign = ContentAlignment.MiddleLeft;
}
}
}

View File

@ -0,0 +1,21 @@
using System;
namespace SystemX.Net.Platform.Common.ExtensionMethods
{
public static class EmEventHandler
{
public static void Handle(this EventHandler eventHandler, object sender, EventArgs eventArgs)
{
var handler = eventHandler;
if (handler != null)
handler(sender, eventArgs);
}
public static void Handle<T>(this EventHandler<T> eventHandler, object sender, T eventArgs)
{
var handler = eventHandler;
if ( handler != null )
handler(sender, eventArgs);
}
}
}

View File

@ -0,0 +1,133 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
namespace SystemX.Net.Platform.Common.ExtensionMethods
{
public static class EmGeneral
{
/// <summary>Indicates whether the specified array is null or has a length of zero.</summary>
/// <param name="array">The array to test.</param>
/// <returns>true if the array parameter is null or has a length of zero; otherwise, false.</returns>
[Pure]
public static bool IsNullOrEmpty(this Array array)
{
return (array == null || array.Length == 0);
}
[Pure]
public static bool IsNullOrEmpty(this IEnumerable enumerable)
{
return (enumerable == null || enumerable.Cast<object>().Count() == 0);
}
[Pure]
public static bool NonNullAny<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
return false;
return source.Any();
}
[Pure]
public static bool NonNullAny<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
return false;
return source.Any(predicate);
}
[Pure]
public static int Clamp(this int val, int min, int max)
{
return val > max ? max : val < min ? min : val;
}
public static double Clamp(this double val, double min, double max)
{
return val > max ? max : val < min ? min : val;
}
[Pure]
public static bool XOR(this bool val1, bool val2)
{
return (val1 && !val2) || (!val1 && val2);
}
[Pure]
public static bool XOR(this object obj1, object obj2)
{
return (obj1 != null && obj2 == null) || (obj1 == null && obj2 != null);
}
[Pure]
public static bool Toggle(this bool fact, bool toggle)
{
return toggle ? ! fact : fact;
}
[Pure]
public static string NonNullEmptySelector(this string str1, string str2)
{
return String.IsNullOrEmpty(str1) ? str2 : str1;
}
[Pure]
public static bool NonNullEqual(this string str1, string str2)
{
return !String.IsNullOrEmpty(str1) && !String.IsNullOrEmpty(str2) && str1 == str2;
}
[Pure]
public static bool NullableEqual(this string str1, string str2)
{
return (str1.IsNullOrEmpty() && str2.IsNullOrEmpty()) || NonNullEqual(str1, str2);
}
public static bool HasTrueValue(this Nullable<bool> nullable)
{
return nullable.HasValue && nullable.Value;
}
}
/// <summary>
/// http://stackoverflow.com/questions/12447156/how-can-i-set-the-column-width-of-a-property-grid
/// </summary>
public static class PropertyGridColumnWidthSetter
{
public static void SetLabelColumnWidth(this PropertyGrid grid, int width)
{
if (grid == null)
return;
FieldInfo fi = grid.GetType().GetField("gridView", BindingFlags.Instance | BindingFlags.NonPublic);
if (fi == null)
return;
Control view = fi.GetValue(grid) as Control;
if (view == null)
return;
MethodInfo mi = view.GetType().GetMethod("MoveSplitterTo", BindingFlags.Instance | BindingFlags.NonPublic);
if (mi == null)
return;
mi.Invoke(view, new object[] {width});
}
}
}

View File

@ -0,0 +1,374 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace SystemX.Net.Platform.Common.ExtensionMethods
{
/// <summary>
/// Linq extension methods
/// </summary>
public static partial class EmLinq
{
// http://stackoverflow.com/questions/1883920/call-a-function-for-each-value-in-a-generic-c-sharp-collection
/// <summary>
/// Generic IEnumerable ForEach extension : typename T is optional. deducible from source
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action"></param>
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (T item in source)
action(item);
}
public static void Iter<T>(this IEnumerable<T> source, Action<T> action) => ForEach(source, action);
public static void Iter<T>(this IEnumerable<T> source, Action<T, int> action)
{
int i = 0;
foreach (T item in source)
action(item, i++);
}
/// <summary>
/// Lazy Foreach : Not evaluated until on demand
/// </summary>
public static IEnumerable<T> ForEachTee<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (T item in source)
{
action(item);
yield return item;
}
}
/// <summary>
/// Non-Generic IEnumerable ForEach extension : typename T should be provided.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action"></param>
public static void ForEach<T>(this IEnumerable source, Action<T> action)
{
foreach (T item in source)
action(item);
}
/// <summary>
/// Non-Generic IEnumerable ForEach extension : typename T should be provided.
/// Lazy Foreach : Not evaluated until on demand
/// </summary>
public static IEnumerable ForEachTee<T>(this IEnumerable source, Action<T> action)
{
foreach (T item in source)
{
action(item);
yield return item;
}
}
/// <summary>
/// Non-Generic IEnumerable Select extension : typename T should be provided.
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <param name="selector"></param>
/// <returns></returns>
public static IEnumerable<TResult> SelectEx<TSource, TResult>(this IEnumerable source, Func<TSource, TResult> selector)
{
foreach (TSource item in source)
yield return selector(item);
}
/// <summary>
/// TResult type 의 enumerable 중에서 TNotCheckType type 이 아닌 것들만 골라서 반환한다. (System.Linq.OfType 의 negation)
/// <para/> System.Linq.SkipWhile() 구문과 같은 역할
/// <para/> TNotCheck 는 TResult type 이어야 함.
/// </summary>
/// <typeparam name="TResult">enumerable 들의 base type. 동시에 반환될 enumerable 의 type</typeparam>
/// <typeparam name="TNotCheckType">제외할 type</typeparam>
/// <param name="source"></param>
/// <returns></returns>
public static IEnumerable<TResult> OfNotType<TResult, TNotCheckType>(this IEnumerable source) where TNotCheckType : TResult
{
if (source == null) throw new ArgumentNullException("source");
return OfNotTypeIterator<TResult, TNotCheckType>(source);
}
private static IEnumerable<TResult> OfNotTypeIterator<TResult, TNotCheckType>(IEnumerable source)
{
foreach (object obj in source)
{
if (!(obj is TNotCheckType))
yield return (TResult)obj;
}
}
/// <summary>
/// Select Non null element from enumerable
/// </summary>
public static IEnumerable<TResult> OfNotNull<TResult>(this IEnumerable<TResult> source) where TResult : class
{
if (source == null) throw new ArgumentNullException("source");
foreach (var s in source)
{
if ( s != null )
yield return s;
}
}
// http://stackoverflow.com/questions/2471588/how-to-get-index-using-linq
public static Nullable<int> FindIndex<T>(this IEnumerable<T> items, Predicate<T> predicate)
{
int index = 0;
foreach (var item in items)
{
if (predicate(item))
return index;
index++;
}
return null;
}
public static HashSet<T> ToHashSet<T>(this IEnumerable<T> items)
{
var hash = new HashSet<T>();
items.ForEach(i => hash.Add(i));
return hash;
}
/// <summary>
/// 두개의 set 이 동일한지 비교. see SequenceEqual
/// </summary>
public static bool SetEqual<T>(this IEnumerable<T> first, IEnumerable<T> second)
{
HashSet<T> firstSet = first.ToHashSet();
foreach (var e in second)
{
if (!firstSet.Contains(e))
return false;
}
HashSet<T> secondSet = second.ToHashSet();
foreach (var e in first)
{
if (!secondSet.Contains(e))
return false;
}
return true;
}
public static bool RemoveTail(this IList list)
{
if (list.IsNullOrEmpty())
return false;
list.RemoveAt(list.Count - 1);
return true;
}
public static T[] ConcatArrays<T>(params T[][] list)
{
var result = new T[list.Sum(a => a.Length)];
int offset = 0;
for (int x = 0; x < list.Length; x++)
{
list[x].CopyTo(result, offset);
offset += list[x].Length;
}
return result;
}
private static Tuple<bool, T> ExtractFirst<T>(this IEnumerable<T> seq)
{
using (var enumerator = seq.GetEnumerator())
{
if (enumerator.MoveNext())
return Tuple.Create(true, enumerator.Current); // => return new Tuple<bool, T>(..) 와 동일
return Tuple.Create(false, default(T));
}
}
/// <summary>
/// http://stackoverflow.com/questions/4354902/check-that-all-items-of-ienumerablet-has-the-same-value-using-linq
/// </summary>
public static bool AllEqual<T>(this IEnumerable<T> source, T target)
{
using (var enumerator = source.GetEnumerator())
{
if (!enumerator.MoveNext())
{
// empty case
return true;
}
var comparer = EqualityComparer<T>.Default;
do
{
if (!comparer.Equals(target, enumerator.Current))
return false;
} while (enumerator.MoveNext());
return true;
}
}
public static bool AllEqual<T>(this IEnumerable<T> source)
{
var pr = source.ExtractFirst();
if (pr.Item1)
return AllEqual(source, pr.Item2);
// empty case
return true;
}
public static T Tee<T>(this T input, Action action)
{
action();
return input;
}
public static T Tee<T>(this T input, Action<T> action)
{
action(input);
return input;
}
public static bool ForAll<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
foreach (var s in source)
{
if (!predicate(s))
return false;
}
return true;
}
public static bool ForAll<T>(this IEnumerable<T> source, Func<T, int, bool> predicate)
{
int i = 0;
foreach (var s in source)
{
if (!predicate(s, i++))
return false;
}
return true;
}
public static bool NoForAll<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
foreach (var s in source)
{
if (predicate(s))
return false;
}
return true;
}
/// <summary>
/// source 를 n 개씩 분할한 sequence 를 반환
/// http://stackoverflow.com/questions/419019/split-list-into-sublists-with-linq
/// </summary>
public static IEnumerable<IEnumerable<T>> SplitByN<T>(this IEnumerable<T> source, int n)
{
return source
.Select((x, i) => new { Index = i, Value = x })
.GroupBy(x => x.Index / n)
.Select(x => x.Select(v => v.Value))
;
}
public static IEnumerable<T> EveryNth<T>(this IEnumerable<T> source, int n)
{
return source.Where((v, i) => i % n == 0);
}
public static IEnumerable<TResult> Zip2<TS1, TS2, TResult>(
this IEnumerable<TS1> s1,
IEnumerable<TS2> s2,
Func<TS1, TS2, TResult> resultSelector) => s1.Zip(s2, resultSelector);
public static IEnumerable<TResult> Zip3<TS1, TS2, TS3, TResult>(
this IEnumerable<TS1> s1,
IEnumerable<TS2> s2,
IEnumerable<TS3> s3,
Func<TS1, TS2, TS3, TResult> resultSelector)
{
using (var e1 = s1.GetEnumerator())
using (var e2 = s2.GetEnumerator())
using (var e3 = s3.GetEnumerator())
{
while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext())
yield return resultSelector(e1.Current, e2.Current, e3.Current);
}
}
public static IEnumerable<TResult> Zip4<TS1, TS2, TS3, TS4, TResult>(
this IEnumerable<TS1> s1,
IEnumerable<TS2> s2,
IEnumerable<TS3> s3,
IEnumerable<TS4> s4,
Func<TS1, TS2, TS3, TS4, TResult> resultSelector)
{
using (var e1 = s1.GetEnumerator())
using (var e2 = s2.GetEnumerator())
using (var e3 = s3.GetEnumerator())
using (var e4 = s4.GetEnumerator())
{
while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext())
yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current);
}
}
public static IEnumerable<int> MinMaxRange(int min, int hop, int max)
{
if (hop <= 0)
throw new ArgumentException("hop counter should be positive.");
for (int i = min; i <= max; i += hop)
yield return i;
}
public static IEnumerable<int> MinMaxRange(int min, int max) => Enumerable.Range(min, max - min);
public static IEnumerable<string> HexRange(int start, int count)
{
foreach (var h in Enumerable.Range(start, count))
{
yield return $"{h:X}";
}
}
/// <summary>
/// Enumerable 의 laziness 를 강제로 실행시켜 evaluation 시킴.
/// </summary>
public static IEnumerable<T> Realize<T>(this IEnumerable<T> seq)
{
//var count = seq.Count(); // count 만으로는, 즉석 evaluation 이 안되는 경우가 존재...???...
var array = seq.ToArray();
return array;
}
}
}