Skip to content

Instantly share code, notes, and snippets.

@unarist
Created January 30, 2017 06:25
Show Gist options
  • Save unarist/e32fec3d5fa51e17562d8bc5a2375aba to your computer and use it in GitHub Desktop.
Save unarist/e32fec3d5fa51e17562d8bc5a2375aba to your computer and use it in GitHub Desktop.
今のMyExtensions
void Main()
{
// Write code to test your extensions here. Press F5 to compile and run.
}
public static class Ex
{
public static string CallerMemberName([CallerMemberName]string member = "") => member;
public static Func<TR> F<TR>(Func<TR> f) { return f; }
public static Func<T, TR> F<T, TR>(Func<T, TR> f) { return f; }
public static Action A(Action f) { return f; }
public static Action<T> A<T>(Action<T> f) { return f; }
public static Action<T1, T2> A<T1, T2>(Action<T1, T2> f) { return f; }
public static Func<T> C<T>(T value) => () => value;
public static T Id<T>(T v) { return v; }
public static Func<T, bool> Eq<T>(T value) where T : IEquatable<T> => x => value.Equals(x);
public static Func<T, bool> Neq<T>(T value) where T : IEquatable<T> => x => !value.Equals(x);
public static IEnumerable<T> Seq<T>(T value) { yield return value; }
public static IEnumerable<T> Seq<T>(params T[] values) => values;
public static T[] Arr<T>(params T[] values) => values;
public static IEnumerable<T> InfSeq<T>(Func<T, T> next, T initial)
{
for(var cur = initial; ; cur = next(cur))
yield return cur;
}
}
public static class Type<T>
{
public static T Construct<TArg1>(TArg1 arg1) =>
(T)typeof(T).GetConstructor(new[] { typeof(TArg1) }).Invoke(new object[] { arg1});
}
public static class HardLinkUtils
{
[StructLayout(LayoutKind.Sequential)]
private struct BY_HANDLE_FILE_INFORMATION
{
public uint FileAttributes;
public FILETIME CreationTime;
public FILETIME LastAccessTime;
public FILETIME LastWriteTime;
public uint VolumeSerialNumber;
public uint FileSizeHigh;
public uint FileSizeLow;
public uint NumberOfLinks;
public uint FileIndexHigh;
public uint FileIndexLow;
}
[DllImport("kernel32.dll", SetLastError = true)]
private static extern void GetFileInformationByHandle(SafeFileHandle handle, out BY_HANDLE_FILE_INFORMATION lpFileInformation);
public static uint GetLinkCount(string filepath)
{
using (var fs = File.OpenRead(filepath))
return GetLinkCount(fs.SafeFileHandle);
}
public static uint GetLinkCount(SafeFileHandle handle)
{
BY_HANDLE_FILE_INFORMATION info;
GetFileInformationByHandle(handle, out info);
return info.NumberOfLinks;
}
}
public static class MyExtensions
{
#region Type Utility
public static T As<T>(this object obj)
where T : class
{
return obj as T;
}
public static IEnumerable<T> AsEnumerable<T>(this object obj)
{
return (IEnumerable<T>)obj;
}
public static object TypeInvokeMember(this object target, string name, BindingFlags invokeAttr, params object[] args)
{
return target.GetType().InvokeMember(name, invokeAttr, null, target, args);
}
public static object InvokeMember(this System.Reflection.IReflect target, string name, BindingFlags invokeAttr, params object[] args)
{
return target.InvokeMember(name, invokeAttr, null, target, args, null, null, null);
}
public static object InvokeMethod(this System.Reflection.IReflect target, string name, params object[] args)
{
return target.InvokeMember(name, BindingFlags.InvokeMethod, null, target, args, null, null, null);
}
#endregion
#region Higher-order
public static T Do<T>(this T param, Action<T> pred)
{
pred(param);
return param;
}
public static TResult Apply<T, TResult>(this T param, Func<T, TResult> func)
{
return func(param);
}
public static TState FoldL<TState>(this TState init, int count, Func<TState, TState> pred)
{
var state = init;
for (var i = 0; i < count; ++i)
state = pred(state);
return state;
}
#endregion
#region Sequence Generator
public static IEnumerable<TResult> Times<TResult>(this int count, Func<TResult> collector)
{
for (var i = 0; i < count; ++i)
yield return collector();
}
public static IEnumerable<T> For<T>(this T initial, Func<T, bool> condition, Func<T, T> step)
{
for (var i = initial; condition(i); i = step(i))
yield return i;
}
public static IEnumerable<int> For(this int initial, Func<int, bool> condition, int step = 1)
{
for (var i = initial; condition(i); i += step)
yield return i;
}
public static IEnumerable<int> UpTo(this int initial, int max, int step = 1)
{
for (var i = initial; i <= max; i += step)
yield return i;
}
public static IEnumerable<int> DownTo(this int initial, int min, int step = 1)
{
for (var i = initial; i >= min; i -= step)
yield return i;
}
#endregion
#region String Utility
public static string FormatWith(this string format, object arg)
{
return string.Format(format, arg);
}
public static string FormatWith(this string format, params object[] args)
{
return string.Format(format, args);
}
public static IEnumerable<string> Format<T>(this IEnumerable<T> values, string format)
{
foreach (var v in values)
yield return string.Format(format, v);
}
public static string JoinToString<T>(this IEnumerable<T> values, string separator)
{
return string.Join(separator, values);
}
public static string Trunc(this string str, int maxlen)
{
return str.Substring(0, Math.Min(str.Length, maxlen));
}
public static string Substring(this string str, string from, string to)
{
var pos = str.IndexOf(from) + from.Length;
var len = str.IndexOf(to) - pos;
return (pos >= 0 && len >= 0) ? str.Substring(pos, len) : null;
}
public static string ApplyAsCharArray(this string str, Func<char[], IEnumerable<char>> op)
{
return new string(op(str.ToCharArray()).ToArray());
}
public static string ToHexString(this ICollection<byte> bytes)
{
var sb = new StringBuilder(bytes.Count * 2);
foreach (var b in bytes)
sb.Append(b.ToString("x2"));
return sb.ToString();
}
public static IEnumerable<string>SplitByLength(this string str, int length)
{
int i = 0;
for (; str.Length - i > length; i += length)
yield return str.Substring(i, length);
if (i < str.Length)
yield return str.Substring(i);
}
#endregion
#region Sequence Extension
public static void ForEach<T>(this IEnumerable<T> source, Action<T> pred)
{
foreach (var item in source)
pred(item);
}
public static void ForEach<T>(this IEnumerable<T> source, Action<T, int> pred)
{
var index = 0;
foreach (var item in source)
pred(item, index++);
}
public static async Task ForEachAsync<T>(this IEnumerable<T> source, Func<T, int, Task> pred)
{
var index = 0;
foreach (var item in source)
await pred(item, index++);
}
public static void ForEach<T>(this IEnumerable<T> source, params Action<T>[] preds)
{
int i = 0;
foreach (var item in source)
preds[i++ % preds.Length](item);
}
public static IEnumerable<T> DoAll<T>(this IEnumerable<T> source, Action<T> pred)
{
foreach (var item in source)
{
pred(item);
yield return item;
}
}
public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source,
Func<TSource> supplier)
{
using (var e = source.GetEnumerator())
{
if (e.MoveNext())
{
do
{
yield return e.Current;
} while (e.MoveNext());
}
else
{
yield return supplier();
}
}
}
public static T FirstOr<T>(this IEnumerable<T> source, T defaultValue)
{
using (var e = source.GetEnumerator())
{
if (e.MoveNext())
{
return e.Current;
}
else
{
return defaultValue;
}
}
}
public static T FirstOr<T>(this IEnumerable<T> source, Func<T, bool> condition , T defaultValue)
{
return source.Where(condition).FirstOr(defaultValue);
}
public static IEnumerable<T> Compact<T>(this IEnumerable<T> source)
{
return source.Where(_ => _ != null);
}
public static IEnumerable<T> WhereNot<T>(this IEnumerable<T> source, Func<T, bool> pred)
{
return source.Where(_ => !pred(_));
}
public static IEnumerable<T> Concat<T>(this IEnumerable<T> source, T item)
{
return source.Concat(Enumerable.Repeat(item, 1));
}
public static Array ToArray<T>(this IEnumerable<T> source, Type elementType)
{
var src_array = source as Array;
if (src_array == null)
src_array = source.ToArray();
var dest = Array.CreateInstance(elementType, src_array.Length);
Array.Copy(src_array, dest, src_array.Length);
return dest;
}
#endregion
#region Expressionized `if`
public static bool Then(this bool cond, Action action)
{
if (cond) action();
return cond;
}
public static bool Else(this bool cond, Action action)
{
if (!cond) action();
return cond;
}
#endregion
#region Encoding
private static Encoding DefaultEncoding { get { return Encoding.UTF8; } }
public static byte[] GetBytes(this string str, Encoding enc = null)
{
enc = enc ?? DefaultEncoding;
return enc.GetBytes(str);
}
public static void Write(this Stream stream, string str, Encoding enc = null)
{
enc = enc ?? DefaultEncoding;
var bytes = enc.GetBytes(str);
stream.Write(bytes, 0, bytes.Length);
}
public static async void WriteAsync(this Stream stream, string str, Encoding enc = null)
{
enc = enc ?? DefaultEncoding;
var bytes = enc.GetBytes(str);
await stream.WriteAsync(bytes, 0, bytes.Length);
}
#endregion
#region Enum
public static bool In<T>(this T target, params T[] values)
{
return values.Any(x => x.Equals(target));
}
#endregion
#region FileDialog
public static string GetFilename(this FileDialog dialog)
=> dialog.ShowDialog() == DialogResult.OK ? dialog.FileName : null;
public static string[] GetFilenames(this FileDialog dialog)
=> dialog.ShowDialog() == DialogResult.OK ? dialog.FileNames : null;
public static string GetSelectedPath(this FolderBrowserDialog dialog)
=> dialog.ShowDialog() == DialogResult.OK ? dialog.SelectedPath : null;
#endregion
public static T DumpWithFormat<T>(this T value, string format)
where T : IFormattable
{
value.ToString(format, null).Dump();
return value;
}
}
public sealed class BinaryReaderBE : BinaryReader
{
public BinaryReaderBE(Stream stream) : base(stream) { }
public BinaryReaderBE(Stream stream, Encoding encoding) : base(stream, encoding) { }
public BinaryReaderBE(Stream stream, Encoding encoding, bool leaveOpen) : base(stream, encoding, leaveOpen) { }
private byte[] buf = new byte[8];
private T ReadBE<T>(Func<byte[], int, T> bitconv, int size)
{
this.Read(buf, 0, size);
Array.Reverse(buf, 0, size);
return bitconv(buf, 0);
}
public override Int16 ReadInt16() => ReadBE(BitConverter.ToInt16, 2);
public override UInt16 ReadUInt16() => ReadBE(BitConverter.ToUInt16, 2);
public override Int32 ReadInt32() => ReadBE(BitConverter.ToInt32, 4);
public override UInt32 ReadUInt32() => ReadBE(BitConverter.ToUInt32, 4);
public override Int64 ReadInt64() => ReadBE(BitConverter.ToInt64, 8);
public override UInt64 ReadUInt64() => ReadBE(BitConverter.ToUInt64, 8);
}
#region Awaiter
public interface IAwaitable
{
IAwaiter GetAwaiter();
}
public interface IAwaiter : ICriticalNotifyCompletion
{
bool IsCompleted { get; }
void GetResult();
}
/// <summary>
/// EnumerableEx.Createの改良版
/// </summary>
public static class EnumerableGenerator
{
public static IEnumerable<T> Create<T>(Func<Func<T, IAwaitable>, Task> create)
{
foreach (var x in new Yielder<T>(create))
yield return x;
}
private class Yielder<T> : IAwaitable, IAwaiter, IDisposable
{
private Action _continuation;
private CancellationTokenSource _cts;
private Task _task;
public Yielder(Func<Func<T, IAwaitable>, Task> create)
{
_cts = new CancellationTokenSource();
_continuation = () =>
_task = create(v =>
{
this.Current = v;
return this;
});
}
public IAwaiter GetAwaiter() => this;
public bool IsCompleted => false;
[System.Security.SecurityCritical]
public void UnsafeOnCompleted(Action continuation) { _continuation = continuation; }
public void OnCompleted(Action continuation) { _continuation = continuation; }
public void GetResult() { _cts.Token.ThrowIfCancellationRequested(); }
public Yielder<T> GetEnumerator() => this;
public T Current { get; private set; }
public void Reset() { throw new NotSupportedException(); }
public bool MoveNext()
{
_continuation();
if (_task.IsFaulted) throw _task.Exception.InnerException;
return !_task.IsCompleted;
}
public void Dispose()
{
if (!_task.IsCompleted)
{
_cts.Cancel();
_continuation();
}
_task.Dispose();
}
}
}
/// <summary>
/// メソッドを一時停止する汎用クラス
/// </summary>
public class YieldState : IAwaitable, IAwaiter
{
private Action _continuation;
#region IAwaitable / IAwaiter
IAwaiter IAwaitable.GetAwaiter() => this;
bool IAwaiter.IsCompleted => false;
void IAwaiter.GetResult() { }
[System.Security.SecurityCritical]
void ICriticalNotifyCompletion.UnsafeOnCompleted(Action continuation) { _continuation = continuation; }
void INotifyCompletion.OnCompleted(Action continuation) { _continuation = continuation; }
#endregion
public IAwaitable Yield() => this;
/// <summary>
/// 再開した場合はtrue、そもそも中断してなければfalseを返す。
/// </summary>
public bool Resume()
{
if (_continuation != null)
{
var cont = _continuation;
_continuation = null;
cont();
return true;
}
else return false;
}
}
#endregion
public static class RegexExtensions
{
private static Func<Group, object> GetSimpleConverter(TypeConverter conv)
=> g => conv.ConvertFrom(g.Value);
private static Func<Group, object> GetArrayConverter(Type arrayType)
{
var elemType = arrayType.GetElementType();
var conv = TypeDescriptor.GetConverter(elemType);
return g => g.Captures.Cast<Capture>().Select(c => conv.ConvertFromString(c.Value)).ToArray(elemType);
}
public static Maybe<Match> AsMaybe(this Match match)
{
return match.Success ? Maybe.Create(match) : new Maybe<Match>();
}
public static T MapGroups<T>(this Match match)
where T : new()
=> Ex.Seq(match).MapGroups<T>().First();
public static IEnumerable<T> MapGroups<T>(this MatchCollection matches)
where T : new()
=> matches.Cast<Match>().MapGroups<T>();
public static IEnumerable<T> MapGroups<T>(this IEnumerable<Match> matches)
where T: new()
{
var props = TypeDescriptor.GetProperties(typeof(T))
.Cast<PropertyDescriptor>()
.Where(prop => !prop.IsReadOnly)
.Select(prop => new
{
Name = prop.Name,
Descriptor = prop,
Type = prop.PropertyType,
Converter = prop.PropertyType.IsArray
? GetArrayConverter(prop.PropertyType)
: GetSimpleConverter(prop.Converter)
}).ToArray();
foreach (Match match in matches)
{
object obj = new T();
foreach (var prop in props)
{
var group = match.Groups[prop.Name];
if (group.Success)
prop.Descriptor.SetValue(obj, prop.Converter(group));
}
yield return (T)obj;
}
}
public static T MapGroups<T>(this Match match, T anonobj)
=> Ex.Seq(match).MapGroups(anonobj).First();
public static IEnumerable<T> MapGroups<T>(this MatchCollection matches, T anonobj)
=> matches.Cast<Match>().MapGroups(anonobj);
public static IEnumerable<T> MapGroups<T>(this IEnumerable<Match> matches, T anonobj)
{
var ctor = typeof(T).GetConstructors().First();
var ctorParams = (
from prop in TypeDescriptor.GetProperties(typeof(T)).Cast<PropertyDescriptor>()
select new
{
Name = prop.Name,
Type = prop.PropertyType,
Converter = prop.PropertyType.IsArray
? GetArrayConverter(prop.PropertyType)
: GetSimpleConverter(prop.Converter),
Default = prop.GetValue(anonobj)
}
).ToList();
return matches
.Select(m =>
from p in ctorParams
let g = m.Groups[p.Name]
select g.Success ? p.Converter(g) : p.Default
)
.Select(args => (T)ctor.Invoke(args.ToArray()));
}
}
public static class PropEq
{
public static EqualityComparer<TObj> Create<TObj, TProp>(Func<TObj, TProp> selector)
=> new PropEq<TObj,TProp>(selector);
public static IEnumerable<TObj> Distinct<TObj, TProp>(this IEnumerable<TObj> source, Func<TObj, TProp> selector)
=> source.Distinct(new PropEq<TObj, TProp>(selector));
}
public class PropEq<TObj,TProp>: EqualityComparer<TObj>
{
private readonly Func<TObj, TProp> selector;
private readonly IEqualityComparer<TProp> propcomp;
public PropEq(Func<TObj, TProp> selector)
{
this.selector = selector;
this.propcomp = EqualityComparer<TProp>.Default;
}
public override bool Equals(TObj a, TObj b)
=> propcomp.Equals(selector(a), selector(b));
public override int GetHashCode(TObj obj)
=> propcomp.GetHashCode(selector(obj));
}
// http://neue.cc/2014/09/24_479.html
public static class ChartExtensions
{
/// <summary>
/// Create Chart control, plot items, dump!
/// </summary>
public static IEnumerable<T> DumpChart<T>(this IEnumerable<T> source, Func<T, object> xSelector, Func<T, object> ySelector, SeriesChartType chartType = SeriesChartType.Column, bool isShowXLabel = false)
{
var chart = new Chart();
chart.ChartAreas.Add(new ChartArea());
var series = new Series { ChartType = chartType };
foreach (var item in source)
{
var x = xSelector(item);
var y = ySelector(item);
var index = series.Points.AddXY(x, y);
series.Points[index].ToolTip = item.ToString();
if (isShowXLabel) series.Points[index].Label = x.ToString();
}
chart.Series.Add(series);
chart.Dump("Chart");
return source;
}
public static IEnumerable<IGrouping<TKey, T>> DumpGroupChart<TKey, T>(this IEnumerable<IGrouping<TKey, T>> source, Func<T, object> xSelector, Func<T, object> ySelector, SeriesChartType chartType = SeriesChartType.Line)
{
var chart = new Chart();
chart.ChartAreas.Add(new ChartArea());
foreach (var g in source)
{
var series = new Series { ChartType = chartType };
foreach (var item in g)
{
var x = xSelector(item);
var y = ySelector(item);
var index = series.Points.AddXY(x, y);
series.Points[index].ToolTip = item.ToString();
}
chart.Series.Add(series);
}
chart.Dump("Chart");
return source;
}
}
// http://qiita.com/lambdalice/items/2e47cb9960c07bf5737a
public static class DisposableExtensions
{
public class Using<T>
where T : IDisposable
{
public T Source { get; set; }
public Using(T source)
{
Source = source;
}
}
/// <summary>
/// Introduce Select(Many) extensions for IDisposable
/// </summary>
public static Using<T> Use<T>(this T source)
where T : IDisposable
{
return new Using<T>(source);
}
public static TResult SelectMany<T, TSecond, TResult>
(this Using<T> source, Func<T, Using<TSecond>> second, Func<T, TSecond, TResult> selector)
where T : IDisposable
where TSecond : IDisposable
{
using (source.Source)
using (var s = second(source.Source).Source)
return selector(source.Source, s);
}
public static TResult Select<T, TResult>(this Using<T> source, Func<T, TResult> selector)
where T : IDisposable
{
using (source.Source)
return selector(source.Source);
}
}
#region Monad
public static class Result
{
public static ResultValue<T> Try<T>(Func<T> func)
{
try
{
return ResultValue<T>.GetSuccess(func());
}
catch (Exception e)
{
return ResultValue<T>.GetFailure(e);
}
}
public struct ResultValue<T>
{
public T Result { get; private set; }
public Exception Exception { get; private set;}
public bool Success => Exception == null;
public static ResultValue<T> GetSuccess(T result)
=> new ResultValue<T> { Result = result };
public static ResultValue<T> GetFailure(Exception ex)
=> new ResultValue<T> { Exception = ex };
public TResult Match<TResult>(Func<T, TResult> mapSuccess, Func<Exception, TResult> mapFailure)
{
return Success ? mapSuccess(Result) : mapFailure(Exception);
}
}
}
public static class Maybe
{
public static Maybe<T> Create<T>(T value)
{
return new Maybe<T>(value);
}
public static Maybe<T> Try<T>(Func<T> func)
{
try
{
return new Maybe<T>(func());
}
catch (Exception)
{
return new Maybe<T>();
}
}
#region Extensions
public static Maybe<TValue> Get<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key)
{
TValue val;
return dict.TryGetValue(key, out val) ? Maybe.Create(val) : new Maybe<TValue>();
}
#endregion
}
public struct Maybe<T>
{
private readonly bool _hasValue;
private readonly T _value;
public bool HasValue { get { return _hasValue; } }
public T Value { get { return _value; } }
public Maybe(T value)
{
_value = value;
_hasValue = true;
}
#region TryFunc Supports
public delegate bool TryFunc(out T result);
public static Maybe<T> FromTry(TryFunc f) { T ret; return f(out ret) ? new Maybe<T>(ret) : new Maybe<T>(); }
public delegate bool TryFunc<T1>(T1 t1, out T result);
public static Maybe<T> FromTry<T1>(TryFunc<T1> f, T1 t1) { T ret; return f(t1, out ret) ? new Maybe<T>(ret) : new Maybe<T>(); }
#endregion
public Maybe<TResult> Select<TResult>(Func<T, TResult> selector)
{
return HasValue ? Maybe.Create(selector(_value)) : new Maybe<TResult>();
}
public TResult Match<TResult>(Func<T, TResult> just, Func<TResult> nothing)
{
return HasValue ? just(_value) : nothing();
}
}
public static class MatchExt
{
public static MatchState<TResult> BeginMatch<TResult>(this object source)
{
return new MatchState<TResult>(source);
}
}
public struct MatchState<TResult>
{
private readonly object source;
private readonly Maybe<TResult> result;
public Maybe<TResult> Result { get { return result; } }
public MatchState(object source)
{
this.source = source;
this.result = new Maybe<TResult>();
}
public MatchState(object source, Maybe<TResult> result)
{
this.source = source;
this.result = result;
}
public MatchState<TResult> Match<T>(Func<T, TResult> selector)
{
if (!result.HasValue && source is T)
{
return new MatchState<TResult>(this.source, Maybe.Create(selector((T)source)));
}
else
{
return this;
}
}
}
#endregion
public abstract class DisposableBase : IDisposable
{
private object syncRoot = new object();
private bool isDisposed = false;
protected abstract void OnDispose(bool disposing);
private void Dispose(bool disposing)
{
lock (syncRoot)
{
if (isDisposed) return;
OnDispose(disposing);
isDisposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~DisposableBase()
{
Dispose(false);
}
}
// http://neue.cc/2013/12/04_435.html
public static class TaskEnumerableExtensions
{
public static Task WhenAll(this IEnumerable<Task> tasks)
{
return Task.WhenAll(tasks);
}
public static Task<T[]> WhenAll<T>(this IEnumerable<Task<T>> tasks)
{
return Task.WhenAll(tasks);
}
}
/// <summary>
/// 非公開メンバにアクセスするプロキシとして使えるDynamicObject
/// </summary>
public class NonPublicProxy : DynamicObject
{
private static Dictionary<Type, TypeInfo> cache = new Dictionary<System.Type, NonPublicProxy.TypeInfo>();
private readonly TypeInfo info;
private readonly object inst;
class TypeInfo
{
public readonly Type Type;
public readonly Dictionary<string, MemberInfo> Members;
public TypeInfo(Type t)
{
Type = t;
Members = t.GetMembers(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
.Where(mi => mi.MemberType == MemberTypes.Field || mi.MemberType == MemberTypes.Property)
.ToDictionary(m => m.Name);
}
}
public static dynamic GetProxyFor(object instance)
{
return new NonPublicProxy(instance.GetType(), instance);
}
public NonPublicProxy(Type t, object instance)
{
if (!cache.TryGetValue(t, out info))
cache[t] = info = new TypeInfo(t);
inst = instance;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
MemberInfo member;
if (info.Members.TryGetValue(binder.Name, out member))
{
if (member is FieldInfo)
result = ((FieldInfo)member).GetValue(inst);
else
result = ((PropertyInfo)member).GetValue(inst);
return true;
}
else
{
result = null;
return false;
}
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
MemberInfo member;
if (info.Members.TryGetValue(binder.Name, out member))
{
if (member is FieldInfo)
((FieldInfo)member).SetValue(inst, value);
else
((PropertyInfo)member).SetValue(inst, value);
return true;
}
else
return false;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
try
{
result = info.Type.InvokeMember(binder.Name,
BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.NonPublic,
null, inst, args);
return true;
}
catch (MissingMethodException)
{
result = null;
return false;
}
}
}
/// <summary>
/// Provides notifications when the contents of the clipboard is updated.
/// see http://stackoverflow.com/a/11901709/
/// </summary>
public sealed class ClipboardListener
{
// See http://msdn.microsoft.com/en-us/library/ms649021%28v=vs.85%29.aspx
private const int WM_CLIPBOARDUPDATE = 0x031D;
//http://msdn.microsoft.com/en-us/library/ms632599%28VS.85%29.aspx#message_only
private static IntPtr HWND_MESSAGE = new IntPtr(-3);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool AddClipboardFormatListener(IntPtr hwnd);
/// <summary>
/// Occurs when the contents of the clipboard is updated.
/// </summary>
public static event Action ClipboardUpdate = () => { };
public static IObservable<System.Reactive.Unit> ClipboardUpdateAsObservable()
=> Observable.FromEvent(_ => ClipboardUpdate += _, _ => ClipboardUpdate -= _);
private static NotificationForm _form = new NotificationForm();
/// <summary>
/// Hidden form to recieve the WM_CLIPBOARDUPDATE message.
/// </summary>
private class NotificationForm : NativeWindow
{
public NotificationForm()
{
CreateHandle(new CreateParams { Parent = HWND_MESSAGE });
AddClipboardFormatListener(Handle);
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_CLIPBOARDUPDATE)
{
ClipboardUpdate();
}
base.WndProc(ref m);
}
}
}
public static class MyBench
{
public static IEnumerable<TimeSpan> Do(int count, params Action[] testcases)
{
var sw = new Stopwatch();
foreach (var testcase in testcases)
{
sw.Restart();
for (int i = 0; i < count; ++i)
testcase();
sw.Stop();
yield return sw.Elapsed;
}
}
}
public static class AssemblyExporter
{
public static void OpenWithILSpy()
=> Process.Start(@"E:\onlinesoft\Programming\ILSpy\ILSpy.exe", Assembly.GetCallingAssembly().Location);
public enum Kind { Dll, Windows, Console }
public class Options
{
public bool EmbedReferencedAssemblies { get; set; }
public bool EmbedLoadedAssemblies { get; set; }
public IEnumerable<Assembly> EmbedAssemblies { get; set;}
public string Namespace { get; set;}
public Kind Kind { get; set; }
}
private static HashSet<MethodBase> _callerOfHasExported;
public static bool HasExported()
{
if(_callerOfHasExported == null)
_callerOfHasExported = new HashSet<MethodBase>();
_callerOfHasExported.Add(new StackFrame(1).GetMethod());
return false;
}
public static bool IsRunningFromLINQPad()
=> Type.GetType("LINQPad.Util, LINQPad") != null;
public static void Export(string filename)
{
var entrypoint = new StackTrace().GetFrames()
.Select(f => f.GetMethod())
.Last(f => f.DeclaringType.FullName == "UserQuery");
var asm = Mono.Cecil.AssemblyDefinition.ReadAssembly(entrypoint.DeclaringType.Assembly.Location);
var userquery = asm.MainModule.GetType("UserQuery");
// エントリポイントの設定
// also: param == (void|string[]) && ret == (void|int)
var method = userquery.Methods.Where(m => m.Name == "Main" && m.IsStatic).FirstOrDefault();
if (method == null)
{
var ep_class = new Mono.Cecil.TypeDefinition("", "<EntryPoint>", Mono.Cecil.TypeAttributes.Class, asm.MainModule.TypeSystem.Object);
asm.MainModule.Types.Add(ep_class);
var ep_def = userquery.Methods.First(m => m.Name == entrypoint.Name);
ep_def.Attributes = ep_def.Attributes & ~Mono.Cecil.MethodAttributes.Private | Mono.Cecil.MethodAttributes.Assembly;
var ctor_def = userquery.Methods.First(m => m.IsConstructor && !m.HasParameters);
var void_t = asm.MainModule.TypeSystem.Void;
method = new Mono.Cecil.MethodDefinition("Main", Mono.Cecil.MethodAttributes.Static, void_t);
ep_class.Methods.Add(method);
var il = method.Body.GetILProcessor();
il.Emit(Mono.Cecil.Cil.OpCodes.Newobj, ctor_def);
il.Emit(Mono.Cecil.Cil.OpCodes.Call, ep_def);
il.Emit(Mono.Cecil.Cil.OpCodes.Ret);
}
asm.EntryPoint = method;
if (_callerOfHasExported != null)
{
foreach (var m in _callerOfHasExported)
{
// call HasExported を探してtrueで置き換える
}
}
asm.MainModule.Kind = Mono.Cecil.ModuleKind.Windows;
asm.Write(filename);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment