委托自定义属性可空类型

c#中的委托就是安全的指针,它可以帮我们回调函数。 下面看一下如何定义委托:

internal delegate void Feedback(Int32 value);
//我写一句话,其实编译器却把它编译成一个类
internal class Feedback : System.MulticastDelegate 
{
public Feedback(Object object, IntPtr method);
public virtual void Invoke(Int32 value);
public virtual IAsyncResult BeginInvoke(Int32 value,AsyncCallback callback, Object object);
public virtual void EndInvoke(IAsyncResult result);
}

下面在看一下IL代码我们可以更清楚的认识它:

我们知道当我们使用Delegate类的Combine方法时,会把多个委托串成一个链,这里要注意的是如果回调的方法有返回值,那么只会返回最后那个回调方法的值。还有就是如果链上有一个方法抛出异常,那么将不再执行链上的其它方法。下面看一下c#为委托提供的便利语法:

//1.不需要定义委托对象
internal sealed class AClass {
public static void CallbackWithoutNewingADelegateObject() {
ThreadPool.QueueUserWorkItem(SomeAsyncTask, 
5);                 //这里不用写new WaitCallBack(SomeAsyncTask)
}

private static void SomeAsyncTask(Object o) {
Console.WriteLine(o);
}

}


//2.不需要定义回调方法(即匿名委托,c#3.0中的Lambda表达式)
internal sealed class AClass {
public static void CallbackWithoutNewingADelegateObject() {
ThreadPool.QueueUserWorkItem(
delegate(Object obj) { Console.WriteLine(obj); },
5);
}

}


//3.不需要指定回调方法参数
button1.Click +=
delegate { MessageBox.Show("The Button was clicked!"); };

还有c#为我们提供的+=,-=操作符去操作委托就不说了。

下面给出一个自定义属性的应用,由于本人对反射不是很了解,而自定义属性的用处就是在反射里面,所以就不详细说了:

using System;
using System.Diagnostics;
using System.Reflection;

[assembly: CLSCompliant(
true)]
[Serializable]
[DefaultMemberAttribute(
"Main")]
[DebuggerDisplayAttribute(
"Richter", Name = "Jeff", Target = typeof(Program))]
public sealed class Program {
[Conditional(
"Debug")]
[Conditional(
"Release")]

public void DoSomething() { }

public Program() {}

[CLSCompliant(
true)]
[STAThread]
public static void Main() {
ShowAttributes(
typeof(Program));
MemberInfo[] members 
= typeof (Program).FindMembers(MemberTypes.Constructor | MemberTypes.Method,BindingFlags.DeclaredOnly | BindingFlags.Instance |
BindingFlags.Public 
| BindingFlags.Static,Type.FilterName, "*");
foreach (MemberInfo member in members) {
ShowAttributes(member);
}

}


private static void ShowAttributes(MemberInfo attributeTarget) {
Attribute[] attributes 
= Attribute.GetCustomAttributes(attributeTarget);
Console.WriteLine(
"Attributes applied to {0}: {1}",attributeTarget.Name, (attributes.Length == 0 ? "None" : String.Empty));

foreach (Attribute attribute in attributes) {
Console.WriteLine(
" {0}", attribute.GetType().ToString());

if (attribute is DefaultMemberAttribute)
Console.WriteLine(
" MemberName={0}",((DefaultMemberAttribute) attribute).MemberName);

if (attribute is ConditionalAttribute)
Console.WriteLine(
" ConditionString={0}",((ConditionalAttribute) attribute).ConditionString);

if (attribute is CLSCompliantAttribute)
Console.WriteLine(
" IsCompliant={0}",((CLSCompliantAttribute) attribute).IsCompliant);

DebuggerDisplayAttribute dda 
= attribute as DebuggerDisplayAttribute;
if (dda != null{
Console.WriteLine(
" Value={0}, Name={1}, Target={2}",dda.Value, dda.Name, dda.Target);
}

}

Console.WriteLine();
}

}

//输出
Attributes applied to Program:
System.SerializableAttribute
System.Diagnostics.DebuggerDisplayAttribute
Value
=Richter, Name=Jeff, Target=Program
System.Reflection.DefaultMemberAttribute
MemberName
=Main

Attributes applied to DoSomething:
System.Diagnostics.ConditionalAttribute
ConditionString
=Release
System.Diagnostics.ConditionalAttribute
ConditionString
=Debug

Attributes applied to Main:
System.STAThreadAttribute
System.CLSCompliantAttribute
IsCompliant
=True

Attributes applied to .ctor: None

c#的可空类型不是基本类型,当我们定义一个可空类型时,编译出来的仍然是个类,下面看一下这个类的定义:

[Serializable, StructLayout(LayoutKind.Sequential)]
public struct Nullable<T> where T : struct {

private Boolean hasValue = false// Assume null
internal T value = default(T); 
public Nullable(T value) {
this.Value = value;
this.hasValue = true;
}

public Boolean HasValue get return hasValue; } }
public T Value {
get {
if (!hasValue) {
throw new InvalidOperationException(
"Nullable object must have a value.");
}

return value;
}

}

public T GetValueOrDefault() return value; }
public T GetValueOrDefault(T defaultValue) {
if (!HasValue) return defaultValue;
return value;
}

public override Boolean Equals(Object other) {
if (!HasValue) return (other == null);
if (other == nullreturn false;
return value.Equals(other);
}

public override int GetHashCode() {
if (!HasValue) return 0;
return value.GetHashCode();
}

public override String ToString() {
if (!HasValue) return "";
return value.ToString();
}

public static implicit operator Nullable<T>(T value) {
return new Nullable<T>(value);
}

public static explicit operator T(Nullable<T> value) {
return value.Value;
}

}

在c#中我们可以这样定义:Nullable<int> x=5;也可以int? x=5;后一种写法更简便。这里我们看到了一个?,c#还定义了一个两个??的操作符。比如我们写:string filename=GetFileName()??"Default"  这个意思就是如果??前面的值不为null就返回前面的值,如果为空就返回后面的值。其实我们可以用三元操作符改写上面的式子:string filename=GetFileName()==null?GetFileName():"Default"  只不过这样写没有上面的那一种简便。

我们可以对可空类型进行装拆箱操作,可以进行接口调用操作:

Int32? n = 5;
Int32 result 
= ((IComparable) n).CompareTo(5); // Compiles & runs OK
Console.WriteLine(result); // 0

还有当我们调用GetType方法时它返回的可不是System.Nullable<T>哦,看一下:

Int32? x = 5;
// The line below displays "System.Int32"; not "System.Nullable<Int32>"
Console.WriteLine (x.GetType());

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值