Заповедь Android: вы не должны взаимодействовать с объектами пользовательского интерфейса из ваших собственных потоков
Оберните свой тост-дисплей в runOnUIThread(new Runnable() { });
Мне нравится использовать два расширения: InsertWhere
/// <summary>
/// Removes all items from the provided <paramref name="list"/> that match the<paramref name="predicate"/> expression.
/// </summary>
/// <typeparam name="T">The class type of the list items.</typeparam>
/// <param name="list">The list to remove items from.</param>
/// <param name="predicate">The predicate expression to test against.</param>
public static void RemoveWhere<T>(this IList<T> list, Func<T, bool> predicate)
{
T[] copy = new T[] { };
Array.Resize(ref copy, list.Count);
list.CopyTo(copy, 0);
for (int i = copy.Length - 1; i >= 0; i--)
{
if (predicate(copy[i]))
{
list.RemoveAt(i);
}
}
}
/// <summary>
/// Inserts an Item into a list at the first place that the <paramref name="predicate"/> expression fails. If it is true in all cases, then the item is appended to the end of the list.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <param name="obj"></param>
/// <param name="predicate">The sepcified function that determines when the <paramref name="obj"/> should be added. </param>
public static void InsertWhere<T>(this IList<T> list, T obj, Func<T, bool> predicate)
{
for (int i = 0; i < list.Count; i++)
{
// When the function first fails it inserts the obj paramiter.
// For example, in a list myList of ordered Int32's {1,2,3,4,5,10,12}
// Calling myList.InsertWhere( 8, x => 8 > x) inserts 8 once the list item becomes greater then or equal to it.
if(!predicate(list[i]))
{
list.Insert(i, obj);
return;
}
}
list.Add(obj);
}
Изменить:
Talljoe внес некоторые существенные улучшения в RemoveWhere / RemoveAll, которые я был построен на скорую руку. При ~ 3mill элементах, удаляющих каждый третий, новая версия занимает всего ~ 50 миллисекунд (менее 10, если она может вызывать List.RemoveAll!), В отличие от нескольких секунд RemoveWhere (я устал ждать этого.)
Вот его значительно улучшенная версия, еще раз спасибо!
Для решения проблемы преобразования имени класса в верхний регистр URL в проектах MVC я выполняю автопилотирование:
public static class RouteCollectionExt
{
public static Route MapRouteLowercase(this RouteCollection routes, string name, string url, object defaults)
{
var route = new LowercaseRoute(url, new RouteValueDictionary(defaults), new MvcRouteHandler());
routes.Add(name, route);
return route;
}
private class LowercaseRoute : Route
{
public LowercaseRoute(string url, IRouteHandler routeHandler)
: base(url, routeHandler) { }
public LowercaseRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
: base(url, defaults, routeHandler) { }
public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler)
: base(url, defaults, constraints, routeHandler) { }
public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler)
: base(url, defaults, constraints, dataTokens, routeHandler) { }
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
var path = base.GetVirtualPath(requestContext, values);
if (path != null)
{
path.VirtualPath = path.VirtualPath.ToLowerInvariant();
}
return path;
}
}
}
Использование:
routes.MapRouteLowercase(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string guid1 = "936DA01F-9ABD-4d9d-80C7-02AF85C822A8";
string guid2 = "936DA01F-9ABD-4d9d-80C7-02AF85C822A";
Console.WriteLine("guid1: {0}", guid1.IsGuid());
Console.WriteLine("guid2: {0}", guid2.IsGuid());
Console.ReadLine();
}
}
public static class GuidUtility
{
/// <summary>
/// Determines if string is legitimate GUID
/// </summary>
public static Boolean IsGuid(this String s)
{
string pattern = @"^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$";
Regex regex = new Regex(pattern);
return regex.IsMatch(s);
}
}
}
Когда-нибудь работали с Entity Framework и использовали строку кода, похожую на эту, снова и снова?
_context.EmployeeSet.Include("Department")
.Include("Manager").Include( ... ).Select();
Разве это не проще:
_context.EmployeeSet.IncludeCommonReferenceses().Select();
`
internal static class ObjectContextExtensions
{
internal static ObjectQuery<Employee> IncludeCommonReferenceses(this ObjectQuery<Employee> employeeSet)
{
return employeeSet.Include(GetPropertyName<Employee>(e => e.Department))
.Include(GetPropertyName<Employee>(e => e.Manager)).Include( ... );
}
private static string GetPropertyName<T>(Expression<Func<T, object>> subSelector)
{
return ((MemberExpression)subSelector.Body).Member.Name;
}
}
Рекомендую сохранять имена свойств в константах, чтобы избежать многократного отражения.
Сравните любое заданное свойство данного класса fileinfo с другим ..
public static bool compare(this FileInfo F1,FileInfo F2,string propertyName)
{
try
{
System.Reflection.PropertyInfo p1 = F1.GetType().GetProperty(propertyName);
System.Reflection.PropertyInfo p2 = F2.GetType().GetProperty(propertyName);
if (p1.GetValue(F1, null) == p2.GetValue(F1, null))
{
return true;
}
}
catch (Exception ex)
{
return false;
}
return false;
}
Это то, что я часто использую для копирования из потока в другой поток, особенно для копирования материала в MemoryStream.
public static void CopyStream(this Stream destination, Stream source)
{
if (source.CanSeek)
{
source.Position = 0;
}
int Length = 64000;
Byte[] buffer = new Byte[Length];
int bytesRead = source.Read(buffer, 0, Length);
// write the required bytes
while (bytesRead > 0)
{
destination.Write(buffer, 0, bytesRead);
bytesRead = source.Read(buffer, 0, Length);
}
}
Реализация:
MemoryStream result = new MemoryStream();
Stream s = new FileStream(tempDocFile, FileMode.Open);
result.CopyStream(s);
s.Close();
В многопоточных WPF-приложениях (например, при использовании сокетов или таймеров) мне часто приходится вызывать поток GUI для изменения атрибутов WPF-элемента. Это безобразно раздутый код, особенно если учесть, что это нужно делать для каждого метода. Поэтому я сделал этот метод расширения:
/// <summary>
/// Invoke the element's thread using a dispatcher. This is needed for changing WPF element attributes.
/// </summary>
/// <param name="dispatcherObject">The element of which to use the thread.</param>
/// <param name="action">The action to do with the invoked thread.</param>
/// <param name="dispatcherPriority">The priority of this action.</param>
public static void DoInvoked(this System.Windows.Threading.DispatcherObject dispatcherObject, Action action, System.Windows.Threading.DispatcherPriority dispatcherPriority = System.Windows.Threading.DispatcherPriority.Render)
{
if (System.Threading.Thread.CurrentThread == dispatcherObject.Dispatcher.Thread)
{
action();
}
else
{
dispatcherObject.Dispatcher.BeginInvoke(action, dispatcherPriority, null);
}
}
Реализация:
public partial class MainWindow : Window
{
... other code ...
void updateTime(object sender, ElapsedEventArgs e)
{
this.DoInvoked(() => textBoxStatus.Text = "Done.");
}
}
Я бы, наверное, использовал их для ограниченных типов.
Something like:
public class Gallons
{
private int m_gallons;
public Gallons(int count)
{
if(count < 0)
throw new ArgumentException("Cannot have negative gallons");
m_gallons = count;
}
static public Gallons operator + (Gallons left, Gallons right)
{
return new Gallons(left.m_gallons + right.m_gallons);
}
public override string ToString()
{
return m_gallons.ToString();
}
}
public class Feet
{
private int m_feet;
public Feet(int count)
{
if(count < 0)
throw new ArgumentException("Cannot have negative feet");
m_feet = count;
}
static public Feet operator +(Feet left, Feet right)
{
return new Feet(left.m_feet + right.m_feet);
}
public override string ToString()
{
return m_feet.ToString();
}
}
public static class Conversions
{
static public Feet Feet(this int i)
{
return new Feet(i);
}
static public Gallons Gallons(this int i)
{
return new Gallons(i);
}
}
public class Test
{
static public int Main(string[] args)
{
System.Console.WriteLine(2.Feet() + 3.Feet()); // 5
System.Console.WriteLine(3.Gallons() + 4.Gallons()); // 7
System.Console.WriteLine(2.Feet() + 3.Gallons()); // doesn't compile - can't add feet to gallons!
return 0;
}
}