1.静态构造函数中不允许出现访问修饰符,只能是公共的public;
2.在IL编译器中,类型构造方法总是叫.cctor(代表 Class constructor)。
internal class DiagramToolBoxControl : Panel
{
private static List<(ShapeBase shape, string name)> shapeBases;
static DiagramToolBoxControl()
{
shapeBases = new List<(ShapeBase shape, string name)>();
}
}
public virtual bool IsAssignableFrom (Type? c)
如果满足下列任一条件,则为 true:
1、c 和当前实例表示相同类型;
2、c 是从当前实例直接或间接派生的。如果继承于当前实例,则 c 是从当前实例直接派生的;如果继承于从当前实例继承的接连一个或多个类,则 c 是从当前实例间接派生的;
3、当前实例是 c 实现的一个接口;
4、c 是一个泛型类型参数,并且当前实例表示 c 的约束之一;
5、c 表示一个值类型,并且当前实例表示 Nullable(在 Visual Basic 中为 Nullable(Of c));
如果不满足上述任何一个条件或者 c 为 false,则为 null。
ShapeBase? shape = Activator.CreateInstance(type, true) as ShapeBase;
摘要:
Creates an instance of the specified type using that type’s parameterless constructor.
(使用该类型的无参数构造函数创建指定类型的实例。)
参数:
type:The type of object to create.(要创建的对象的类型。)
nonPublic:
true if a public or nonpublic parameterless constructor can match; false if only a public parameterless constructor can match.
(如果公共或非公共无参数构造函数可以匹配,则为 true;如果只有公共无参数构造函数可以匹配,则为 false。)
A reference to the newly created object.
(对新创建的对象的引用。)
enum不可使用as显式类型转换
as 运算符必须与引用类型或可以为 null 的类型一起使用(“ConnectorDirection”是不可为 null 值的类型)
base 关键字用于从派生类中访问基类的成员:
调用基类上已被其他方法重写的方法。
指定创建派生类实例时应调用的基类构造函数。
基类访问只能在构造函数、实例方法或实例属性访问器中进行。
从静态方法中使用 base 关键字是错误的。
internal class Program
{
static void Main(string[] args)
{
Parent p = new Child("aoteman");
Console.ReadLine();
}
}
class Parent
{
public Parent(string name)
{
Console.WriteLine("Parent: " + name);
}
}
class Child : Parent
{
public Child(string name): base(name)
{
Console.WriteLine("Child: " + name);
}
}
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
注释:避免绘图闪烁问题
同理:
this.SetStyle(ControlStyles.OptimizedDoubleBuffer
| ControlStyles.ResizeRedraw
| ControlStyles.Selectable
| ControlStyles.AllPaintingInWmPaint
| ControlStyles.UserPaint
| ControlStyles.SupportsTransparentBackColor,
true);
或:
this.SetStyle(ControlStyles.UserPaint, true);//自绘
this.SetStyle(ControlStyles.DoubleBuffer, true);// 双缓冲
this.SetStyle(ControlStyles.ResizeRedraw, true); //调整大小时重绘
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); //禁止檫除背景
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); //双缓冲
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); //透明效果
implicit 关键字用于声明隐式的用户定义类型转换运算符。如果可以确保转换过程不会造成数据丢失,则可使用该关键字在用户定义类型和其他类型之间进行隐式转换。隐式转换可以通过消除不必要的类型转换来提高源代码的可读性。但是,因为隐式转换不需要程序员将一种类型显式强制转换为另一种类型,所以使用隐式转换时必须格外小心,以免出现意外结果。一般情况下,隐式转换运算符应当从不引发异常并且从不丢失信息,以便可以在程序员不知晓的情况下安全使用它们。如果转换运算符不能满足那些条件,则应将其标记为 explicit。
internal class Program
{
static void Main(string[] args)
{
A a1 = new A(16.8f);
float f1 = a1;
A a2 = f1;
Console.WriteLine(f1);
Console.WriteLine(a1);
Console.WriteLine(a2);
Console.ReadLine();
}
}
class A
{
public A(float f)
{
p = f;
}
public float p { get; }
public static implicit operator A(float f)
{
return new A(f);
}
public static implicit operator float(A a)
{
return a.p;
}
}
explicit 关键字的作用是强制转换用户自定义的类型转换运算符。通常前面用static后面使用operator,一般是把当前类型转换成另一个类型(将原类型的转换成目标类型)。
internal class Program
{
static void Main(string[] args)
{
A a1 = new A(16.8f);
B b1 = (B)a1;
A a2 = (A)b1;
Console.WriteLine(a1.p);
Console.WriteLine(b1.p);
Console.WriteLine(a2.p);
Console.ReadLine();
}
}
class A
{
public A(float f)
{
p = f;
}
public float p { get; }
public static explicit operator B(A a)
{
return new B(a.p * 2);
}
}
class B
{
public B(float f)
{
p = f;
}
public float p { get; }
public static explicit operator A(B b)
{
return new A(b.p * 10f);
}
}
OnDragStart是在鼠标拖拽开始时触发,
OnDragEnd是在鼠标拖拽结束触发。
OnDragDrop是在鼠标拖拽完成后触发
public void OnDragStart(dfControl control, dfDragEventArgs dragEvent)
{
Debug.Log("DragStartDragStartDragStartDragStartDragStart");
dragEvent.State = dfDragDropState.Dragging;
}
public void OnDragEnd(dfControl control, dfDragEventArgs dragEvent)
{
Debug.Log("DragEndDragEndDragEndDragEndDragEndDragEndDragEnd");
// Add event handler code here
}
public void OnDragDrop(dfControl control, dfDragEventArgs dragEvent)
{
Debug.Log("DragDropDragDropDragDropDragDropDragDropDragDrop");
// Add event handler code here
}
分析:OnDragStart是在拖拽开始时就会执行,值得注意的是虽然OnDragEnd是在拖拽结束时触发,可是是在OnDragStart必须设置其拖拽事件的状态为dfDragDropState.Dragging,不然OnDragEnd将不执行。
OnDragDrop 是将此控件拖拽到另外一个控件中触发。