此文章转载于http://www.raysoftware.cn/?p=278&tdsourcetag=s_pcqq_aiomsg的博客

从Delphi支持泛型的第一天起就有了一种新的动态数组类型,泛型化的动态数组–TArray.
虽然这个类型比较方便,但是却没有提供更丰富的操作.因为XE4中提供了对数据类型的Helper扩展,例如StringHelper,企图实现一个TArrayHelper但是发现Helper不支持泛型的类型.
没办法只好包装了一个record,好处是似乎只要支持泛型的Delphi版本都可以支持.使用Demo如下:

procedure TestTArrayEx;
var
a, b, c: TArrayEx<Integer>;
f: TArrayEx<Single>;
s : TArrayEx<string>;
//
i: Integer;
z: array of Integer;
args:TArrayEx<string>;
begin
// assign a := [2, 2, 3, 4];
s := ['haha', 'hello']; // clone
b := a.Clone; // 给元素赋值
b[0] := 5; // operator +
c := a + b; c := 88 + c + 99;
a.Append([10, 20, 30]);
a.Insert(2, 1000);
a.Insert(2, [1000, 45]); a[0] := 7; // Unique
c.Unique;
// Delete
c.Delete(0, 3); // compare
if c = z then
// for in loop
for i in c do
if i = 0 then
begin
//
end; //
f := [1, 2, 3.1415926];
f.Size := 200;
if f[0] = 1.2 then
begin
f.Size := 100;
end;
end;

这些成员方法和操作符重载都是原来的TArray所不具备的.注重开发效率可以用这个办法封装一些类型,简化操作.
TArrayEx的实现代码在下面.记得必须是支持泛型版本的Delphi哦,也就是至少要Delphi2009版以后的.

unit TJArrayEx;

{ ******************************************************************************
泛型动态数组的扩展. sample: var
a, b, c: TArrayEx<Integer>;
f: TArrayEx<Single>;
s : TArrayEx<string>;
//
i: Integer;
z: array of Integer;
args:TArrayEx<string>;
begin
// assign a := [2, 2, 3, 4];
s := ['haha', 'hello']; // clone
b := a.Clone; // 给元素赋值
b[0] := 5; // operator +
c := a + b; c := 88 + c + 99;
a.Append([10, 20, 30]);
a.Insert(2, 1000);
a.Insert(2, [1000, 45]); a[0] := 7; // Unique
c.Unique;
// Delete
c.Delete(0, 3); // compare
if c = z then
// for in loop
for i in c do
if i = 0 then
begin
//
end; // f := [1, 2, 3.1415926];
f.Size := 200;
if f[0] = 1.0 then
begin
end; args := ['38inch','45inch','XL','XL2','X','38inch','45inch'];
args.Unique;
//sort
args.Sort;
//search
if args.BinarySearch('XL',i) then
ShowMessageFmt('foud index:%d',[i]); end; ****************************************************************************** }
interface uses System.Generics.Defaults, System.SysUtils; type
TArrayEx<T> = record
strict private
type
TEnumerator = class
private
FValue: TArray<T>;
FIndex: NativeInt;
function GetCurrent: T;
public
constructor Create(const AValue: TArray<T>);
function MoveNext: Boolean;
property Current: T read GetCurrent;
end;
public
function GetEnumerator(): TEnumerator;
strict private
FData: TArray<T>;
function GetRawData: TArray<T>;
function GetElements(Index: Integer): T;
procedure SetElements(Index: Integer; const Value: T);
private
class function EqualArray(A, B: TArray<T>): Boolean; static;
class function CompareT(const A, B: T): Boolean; static;
class procedure CopyArray(var FromArray, ToArray: TArray<T>;
FromIndex: NativeInt = 0; ToIndex: NativeInt = 0;
Count: NativeInt = -1); static;
class procedure MoveArray(var AArray: array of T;
FromIndex, ToIndex, Count: Integer); static;
class function DynArrayToTArray(const Value: array of T): TArray<T>; static;
class function Min(A, B: NativeInt): NativeInt; static;
procedure QuickSort(const Comparer: IComparer<T>; L, R: Integer);
public // operators
class operator Implicit(Value: TArray<T>): TArrayEx<T>; overload;
class operator Implicit(Value: array of T): TArrayEx<T>; overload;
(*
这个无解,Delphi不允许array of T作为返回值.也就是这个转换是被废了.只好用AssignTo
class operator Implicit(Value: TArrayEx<T>):array of T; overload;
*)
class operator Implicit(Value: TArrayEx<T>): TArray<T>; overload;
class operator Explicit(Value: TArrayEx<T>): TArray<T>; overload;
class operator Explicit(Value: array of T): TArrayEx<T>; overload; class operator Add(A, B: TArrayEx<T>): TArrayEx<T>; overload;
class operator Add(A: TArrayEx<T>; const B: T): TArrayEx<T>; overload;
class operator Add(const A: T; B: TArrayEx<T>): TArrayEx<T>; overload;
class operator Add(A: TArrayEx<T>; B: array of T): TArrayEx<T>; overload;
class operator Add(A: array of T; B: TArrayEx<T>): TArrayEx<T>; overload;
class operator In (A: T; B: TArrayEx<T>): Boolean; overload;
//
class operator Equal(A, B: TArrayEx<T>): Boolean; overload;
class operator Equal(A: TArrayEx<T>; B: TArray<T>): Boolean; overload;
class operator Equal(A: TArray<T>; B: TArrayEx<T>): Boolean; overload;
class operator Equal(A: array of T; B: TArrayEx<T>): Boolean; overload;
class operator Equal(A: TArrayEx<T>; B: array of T): Boolean; overload; public
procedure SetLen(Value: NativeInt); inline;
function GetLen: NativeInt; inline;
function ByteLen: NativeInt; inline;
class function Create(Value: array of T): TArrayEx<T>; overload; static;
class function Create(Value: TArrayEx<T>): TArrayEx<T>; overload; static;
class function Create(const Value: T): TArrayEx<T>; overload; static;
function Clone(): TArrayEx<T>;
procedure SetValue(Value: array of T);
function ToArray(): TArray<T>;
function SubArray(AFrom, ACount: NativeInt): TArrayEx<T>;
procedure Delete(AFrom, ACount: NativeInt); overload;
procedure Delete(AIndex: NativeInt); overload;
procedure Append(Values: TArrayEx<T>); overload;
procedure Append(const Value: T); overload;
procedure Append(Values: array of T); overload;
procedure Append(Values: TArray<T>); overload;
function Insert(AIndex: NativeInt; const Value: T): NativeInt; overload;
function Insert(AIndex: NativeInt; const Values: array of T)
: NativeInt; overload;
function Insert(AIndex: NativeInt; const Values: TArray<T>)
: NativeInt; overload;
function Insert(AIndex: NativeInt; const Values: TArrayEx<T>)
: NativeInt; overload;
procedure Unique();
// 排序
procedure Sort(); overload;
procedure Sort(const Comparer: IComparer<T>); overload;
procedure Sort(const Comparer: IComparer<T>;
Index, Count: Integer); overload;
// 搜索
function BinarySearch(const Item: T; out FoundIndex: Integer;
const Comparer: IComparer<T>; Index, Count: Integer): Boolean; overload;
function BinarySearch(const Item: T; out FoundIndex: Integer;
const Comparer: IComparer<T>): Boolean; overload;
function BinarySearch(const Item: T; out FoundIndex: Integer)
: Boolean; overload; property Size: NativeInt read GetLen write SetLen;
property Len: NativeInt read GetLen write SetLen;
property RawData: TArray<T> read GetRawData;
property Elements[Index: Integer]: T read GetElements
write SetElements; default;
end; implementation uses System.RTLConsts; class operator TArrayEx<T>.Add(A, B: TArrayEx<T>): TArrayEx<T>;
begin
Result := A.Clone;
Result.Append(B);
end; class operator TArrayEx<T>.Add(A: TArrayEx<T>; const B: T): TArrayEx<T>;
begin
Result := A.Clone;
Result.Append(B);
end; class operator TArrayEx<T>.Add(const A: T; B: TArrayEx<T>): TArrayEx<T>;
begin
Result.SetValue([A]);
Result.Append(B);
end; class operator TArrayEx<T>.Add(A: TArrayEx<T>; B: array of T): TArrayEx<T>;
begin
Result := A.Clone;
Result.Append(B);
end; class operator TArrayEx<T>.Add(A: array of T; B: TArrayEx<T>): TArrayEx<T>;
begin
Result.FData := DynArrayToTArray(A);
Result.Append(B);
end; class operator TArrayEx<T>.In(A: T; B: TArrayEx<T>): Boolean;
var
Tmp: T;
begin
Result := False;
for Tmp in B.FData do
if CompareT(A, Tmp) then
begin
Result := True;
Break;
end;
end; class operator TArrayEx<T>.Equal(A, B: TArrayEx<T>): Boolean;
begin
Result := EqualArray(A.FData, B.FData);
end; class operator TArrayEx<T>.Equal(A: TArrayEx<T>; B: TArray<T>): Boolean;
begin
Result := EqualArray(A.FData, B);
end; class operator TArrayEx<T>.Equal(A: TArray<T>; B: TArrayEx<T>): Boolean;
begin
Result := EqualArray(A, B.FData);
end; class operator TArrayEx<T>.Equal(A: array of T; B: TArrayEx<T>): Boolean;
begin
Result := EqualArray(DynArrayToTArray(A), B.FData);
end; class operator TArrayEx<T>.Equal(A: TArrayEx<T>; B: array of T): Boolean;
begin
Result := EqualArray(A.FData, DynArrayToTArray(B));
end; function TArrayEx<T>.BinarySearch(const Item: T; out FoundIndex: Integer;
const Comparer: IComparer<T>; Index, Count: Integer): Boolean;
var
L, H: Integer;
mid, cmp: Integer;
begin
if (Index < Low(FData)) or ((Index > High(FData)) and (Count > 0)) or
(Index + Count - 1 > High(FData)) or (Count < 0) or (Index + Count < 0) then
raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
if Count = 0 then
begin
FoundIndex := Index;
Exit(False);
end; Result := False;
L := Index;
H := Index + Count - 1;
while L <= H do
begin
mid := L + (H - L) shr 1;
cmp := Comparer.Compare(FData[mid], Item);
if cmp < 0 then
L := mid + 1
else
begin
H := mid - 1;
if cmp = 0 then
Result := True;
end;
end;
FoundIndex := L;
end; function TArrayEx<T>.BinarySearch(const Item: T; out FoundIndex: Integer;
const Comparer: IComparer<T>): Boolean;
begin
Result := BinarySearch(Item, FoundIndex, Comparer, Low(FData), Length(FData));
end; function TArrayEx<T>.BinarySearch(const Item: T;
out FoundIndex: Integer): Boolean;
begin
Result := BinarySearch(Item, FoundIndex, TComparer<T>.Default, Low(FData),
Length(FData));
end; function TArrayEx<T>.ByteLen: NativeInt;
begin
Result := Length(FData) * Sizeof(T);
end; class function TArrayEx<T>.Min(A, B: NativeInt): NativeInt;
begin
Result := A;
if Result > B then
Result := B;
end; class procedure TArrayEx<T>.CopyArray(var FromArray, ToArray: TArray<T>;
FromIndex, ToIndex, Count: NativeInt);
var
i: Integer;
begin
if Count = 0 then
Exit;
if Count < 0 then
Count := Min(Length(FromArray), Length(ToArray));
if Length(FromArray) < (FromIndex + Count) then
Count := Length(FromArray) - FromIndex;
if Length(ToArray) < (ToIndex + Count) then
Count := Length(ToArray) - ToIndex; if Count > 0 then
for i := 0 to Count - 1 do
ToArray[ToIndex + i] := FromArray[FromIndex + i];
end; class procedure TArrayEx<T>.MoveArray(var AArray: array of T;
FromIndex, ToIndex, Count: Integer);
var
i: Integer;
begin
if Count > 0 then
begin
if FromIndex < ToIndex then
for i := Count - 1 downto 0 do
AArray[ToIndex + i] := AArray[FromIndex + i]
else if FromIndex > ToIndex then
for i := 0 to Count - 1 do
AArray[ToIndex + i] := AArray[FromIndex + i];
end;
end; procedure TArrayEx<T>.QuickSort(const Comparer: IComparer<T>; L, R: Integer);
var
i, J: Integer;
pivot, temp: T;
begin
if (Length(FData) = 0) or ((R - L) <= 0) then
Exit;
repeat
i := L;
J := R;
pivot := FData[L + (R - L) shr 1];
repeat
while Comparer.Compare(FData[i], pivot) < 0 do
Inc(i);
while Comparer.Compare(FData[J], pivot) > 0 do
Dec(J);
if i <= J then
begin
if i <> J then
begin
temp := FData[i];
FData[i] := FData[J];
FData[J] := temp;
end;
Inc(i);
Dec(J);
end;
until i > J;
if L < J then
QuickSort(Comparer, L, J);
L := i;
until i >= R;
end; class function TArrayEx<T>.DynArrayToTArray(const Value: array of T): TArray<T>;
var
i: Integer;
begin
SetLength(Result, Length(Value));
for i := Low(Value) to High(Value) do
Result[i] := Value[i];
end; class function TArrayEx<T>.EqualArray(A, B: TArray<T>): Boolean;
var
i: Integer;
begin
Result := True;
if A = B then
Exit;
if Length(A) <> Length(B) then
begin
Result := False;
end
else
begin
for i := Low(A) to High(A) do
if not CompareT(A[i], B[i]) then
begin
Result := False;
Break;
end;
end;
end; class function TArrayEx<T>.CompareT(const A, B: T): Boolean;
var
Compare: IComparer<T>;
begin
Compare := TComparer<T>.Default;
Result := Compare.Compare(A, B) = 0;
end;
// class function TArrayEx<T>.CompareT(const A, B: T): Boolean;
// var
// p1, p2: PByte;
// i: Integer;
// begin
// Result := True;
// p1 := PByte(@A);
// p2 := PByte(@B);
// for i := 0 to Sizeof(T) - 1 do
// begin
// //
// if p1^ <> p2^ then
// begin
// Result := False;
// Exit;
// end;
// Inc(p1);
// Inc(p2);
// end;
// end; function TArrayEx<T>.GetElements(Index: Integer): T;
begin
Result := FData[Index];
end; function TArrayEx<T>.GetEnumerator: TEnumerator;
begin
Result := TEnumerator.Create(FData);
end; function TArrayEx<T>.GetLen: NativeInt;
begin
Result := Length(FData);
end; function TArrayEx<T>.GetRawData: TArray<T>;
begin
Result := FData;
end; class operator TArrayEx<T>.Implicit(Value: TArrayEx<T>): TArray<T>;
begin
SetLength(Result, Length(Value.FData));
CopyArray(Value.FData, Result, 0, 0, Length(Value.FData));
end; class operator TArrayEx<T>.Explicit(Value: array of T): TArrayEx<T>;
begin
Result.SetValue(Value);
end; class operator TArrayEx<T>.Implicit(Value: array of T): TArrayEx<T>;
begin
Result.SetValue(Value);
end; class operator TArrayEx<T>.Implicit(Value: TArray<T>): TArrayEx<T>;
begin
SetLength(Result.FData, Length(Value));
CopyArray(Value, Result.FData, 0, 0, Length(Value));
end; class operator TArrayEx<T>.Explicit(Value: TArrayEx<T>): TArray<T>;
begin
SetLength(Result, Length(Value.FData));
CopyArray(Value.FData, Result, 0, 0, Length(Value.FData));
end; procedure TArrayEx<T>.SetElements(Index: Integer; const Value: T);
begin
FData[Index] := Value;
end; procedure TArrayEx<T>.SetLen(Value: NativeInt);
begin
SetLength(FData, Value);
end; procedure TArrayEx<T>.SetValue(Value: array of T);
begin
FData := DynArrayToTArray(Value);
end; procedure TArrayEx<T>.Sort;
begin
QuickSort(TComparer<T>.Default, Low(FData), High(FData));
end; procedure TArrayEx<T>.Sort(const Comparer: IComparer<T>; Index, Count: Integer);
begin
if (Index < Low(FData)) or ((Index > High(FData)) and (Count > 0)) or
(Index + Count - 1 > High(FData)) or (Count < 0) or (Index + Count < 0) then
raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
if Count <= 1 then
Exit;
QuickSort(Comparer, Index, Index + Count - 1);
end; procedure TArrayEx<T>.Sort(const Comparer: IComparer<T>);
begin
QuickSort(Comparer, Low(FData), High(FData));
end; function TArrayEx<T>.ToArray(): TArray<T>;
begin
SetLength(Result, Length(FData));
CopyArray(FData, Result, 0, 0, Length(FData));
end; class function TArrayEx<T>.Create(Value: array of T): TArrayEx<T>;
begin
Result.SetValue(Value);
end; class function TArrayEx<T>.Create(Value: TArrayEx<T>): TArrayEx<T>;
begin
Result := Value.Clone;
end; class function TArrayEx<T>.Create(const Value: T): TArrayEx<T>;
begin
Result.SetValue([Value]);
end; function TArrayEx<T>.Clone(): TArrayEx<T>;
begin
Result := SubArray(0, Length(FData));
end; function TArrayEx<T>.SubArray(AFrom, ACount: NativeInt): TArrayEx<T>;
begin
SetLength(Result.FData, ACount);
CopyArray(FData, Result.FData, AFrom, 0, ACount);
end; procedure TArrayEx<T>.Delete(AFrom, ACount: NativeInt);
begin
if AFrom >= Length(FData) then
Exit;
if (AFrom + ACount) > Length(FData) then
ACount := Length(FData) - AFrom; MoveArray(FData, AFrom + ACount, AFrom, Length(FData) - (AFrom + ACount));
SetLength(FData, Length(FData) - ACount);
end; procedure TArrayEx<T>.Delete(AIndex: NativeInt);
begin
Delete(AIndex, 1);
end; procedure TArrayEx<T>.Append(Values: TArrayEx<T>);
begin
Insert(Length(FData), Values);
end; procedure TArrayEx<T>.Append(Values: TArray<T>);
begin
Insert(Length(FData), Values);
end; procedure TArrayEx<T>.Append(const Value: T);
begin
SetLength(FData, Length(FData) + 1);
FData[High(FData)] := Value;
end; procedure TArrayEx<T>.Append(Values: array of T);
begin
Insert(Length(FData), Values);
end; function TArrayEx<T>.Insert(AIndex: NativeInt; const Value: T): NativeInt;
var
i: Integer;
begin
Result := -1;
if (AIndex > Length(FData)) or (AIndex < 0) then
Exit;
SetLength(FData, Length(FData) + 1);
MoveArray(FData, AIndex, AIndex + 1, Length(FData) - AIndex);
FData[AIndex] := Value;
Result := AIndex;
end; function TArrayEx<T>.Insert(AIndex: NativeInt; const Values: array of T)
: NativeInt;
var
i: Integer;
begin
SetLength(FData, Length(FData) +Length(Values));
MoveArray(FData, AIndex, AIndex + Length(Values), Length(FData) - AIndex);
for i := 0 to Length(Values) - 1 do
FData[AIndex + i] := Values[i];
Result := AIndex;
end; function TArrayEx<T>.Insert(AIndex: NativeInt; const Values: TArray<T>)
: NativeInt;
var
i: Integer;
begin
SetLength(FData, Length(FData) + Length(Values));
MoveArray(FData, AIndex, AIndex + Length(Values), Length(FData) - AIndex);
for i := 0 to Length(Values) - 1 do
FData[AIndex + i] := Values[i];
Result := AIndex;
end; function TArrayEx<T>.Insert(AIndex: NativeInt; const Values: TArrayEx<T>)
: NativeInt;
begin
Result := Insert(AIndex, Values.ToArray);
end; procedure TArrayEx<T>.Unique();
var
i, J: Integer;
Tmp: TArrayEx<T>;
Flag: Boolean;
begin for i := High(FData) downto Low(FData) do
begin
Flag := False;
for J := High(Tmp.FData) downto Low(Tmp.FData) do
begin
if CompareT(FData[i], Tmp[J]) then
begin
Flag := True;
Break;
end;
end;
if not Flag then
Tmp.Append(FData[i]);
end;
FData := Tmp.FData;
end; { TArrayEx<T>.TEnumerator } constructor TArrayEx<T>.TEnumerator.Create(const AValue: TArray<T>);
begin
FValue := AValue;
FIndex := -1;
end; function TArrayEx<T>.TEnumerator.GetCurrent: T;
begin
Result := FValue[FIndex];
end; function TArrayEx<T>.TEnumerator.MoveNext: Boolean;
begin
Result := False;
if (FIndex >= Length(FValue)) then
Exit; Inc(FIndex);
Result := FIndex < Length(FValue);
end; end.

  

Delphi泛型动态数组的扩展--转贴的更多相关文章

  1. Delphi 的动态数组

    传统的Pascal 语言其数组大小是预先确定的,当你用数组结构声明数据类型时,你必须指定数组元素的个数.专业程序员也许知道些许动态数组的实现技术,一般是采用指针,用手工分配并释放所需的内存. Delp ...

  2. [转]delphi 删除动态数组的指定元素

    type TArr = array of TPoint; {把数组先定义成一个类型会方便许多, 这里仅用 TPoint 测试} {删除动态数组指定元素的过程: 参数 arr 是数组名, 参数 Inde ...

  3. delphi动态数组指针问题

    就一个button事件 procedure TForm1.btn7Click(Sender: TObject); Type TMyArr = array of array of array of In ...

  4. 扩展 delphi 泛型 以实现类似lambda功能 , C#中的any count first last 等扩展方法

    扩展 delphi 泛型 以实现类似lambda功能 , C#中的any count first last 等扩展方法 在C#中对泛型的扩展,输入参数是泛型本身的内容,返回值则是bool.基于这一点, ...

  5. Delphi内存管理(Integer、Boolean、Record、枚举等都是在作用域内编译器自动申请内存,出了作用域自动释放;另外,字符串、Variant、动态数组、接口也是由Delphi自动管理)

    一.什么是堆.栈? 程序需要的内存空间分为 heap(堆) 和 stack(栈),heap 是自由存储区, stack 是自动存储区,使用 heap 需要手动申请.手动释放, stack 是自动申请. ...

  6. delphi 静态3维数组。 严重占用堆栈 切记。 应该用动态数组, 非要用静态数组的话, 要在编译器里 把 堆栈 调大

    delphi 代码正确, 但是运行就崩溃. 原因为 定义了  一些   静态3维数组. 应该扩大 软件的 堆栈 设置.    然后正常解决问题 静态3维数组.   严重占用堆栈   切记. 应该用动态 ...

  7. 一篇文章让你了解动态数组的数据结构的实现过程(Java 实现)

    目录 数组基础简单回顾 二次封装数组类设计 基本设计 向数组中添加元素 在数组中查询元素和修改元素 数组中的包含.搜索和删除元素 使用泛型使该类更加通用(能够存放 "任意" 数据类 ...

  8. [数据结构1.2-线性表] 动态数组ArrayList(.NET源码学习)

    [数据结构1.2-线性表] 动态数组ArrayList(.NET源码学习) 在C#中,存在常见的九种集合类型:动态数组ArrayList.列表List.排序列表SortedList.哈希表HashTa ...

  9. 常用数据结构-线性表及Java 动态数组 深究

    [Java心得总结六]Java容器中——Collection在前面自己总结的一篇博文中对Collection的框架结构做了整理,这里深究一下Java中list的实现方式 1.动态数组 In compu ...

随机推荐

  1. Two ways to invert a string

    package com.itheima_07; import java.util.Scanner; /* * 字符串反转 * 举例:键盘录入”abc” * 输出结果:”cba” * * 分析: * A ...

  2. public 类、default 类、内部类、匿名内部类

    0.父类里private的成员变量,子类只有拥有权,没有使用权. 1.default 类 和public 类 package HelloWorld; public class HelloWorld { ...

  3. Oracle EBS AR 客户取数SQL

    SELECT acct.cust_account_id, acct.party_id, acct.account_number, party.party_name, lkp1.meaning part ...

  4. Jmeter入门--安装教程

    jmeter简介 Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域. 它可以用于测试静态和动 ...

  5. C#.net XML的序列化与反序列化

    /// <summary> /// 将一个对象序列化为XML字符串 /// </summary> /// <param name="o">要序列 ...

  6. C#对DataTable里数据排序的方法

    protected void Page_Load(object sender, EventArgs e) { DataTable dt = new DataTable(); dt.Columns.Ad ...

  7. 15. DML, DDL, LOGON 触发器

    触发器可以理解为由特定事件触发的存储过程, 和存储过程.函数一样,触发器也支持CLR,目前SQL Server共支持以下几种触发器: 1. DML触发器, 表/视图级有效,可由DML语句 (INSER ...

  8. EXC_BAD_ACCESS错误

    EXC_BAD_ACCESS错误 一直都是使用ARC开发,咋就莫名其妙的出现这种EXC_BAD_ACCESS错误. 一直都是是怀疑在block中有着特殊处理,导致了使用时出现了这种错误,查找了好久.. ...

  9. 如何生成.mobileprovision文件

    如何生成.mobileprovision文件 本人视频教程系列 **.mobileprovision文件的生成的第一步就需要你提供一个用于开发的App ID 1. 创建App ID 创建一个bundl ...

  10. android-eclips中logcat不显示信息的问题解决

    time:2015/11/20 1. logcat窗口不显示问题 解决: 参考[1] 2. logcat中不显示信息 (1)红米手机 (2)解决问题 * 有些文章提到重启eclipse,或者重启手机. ...