C#中Property和Attribute的区别实例详解

本文实例分析了C#中Property和Attribute的区别。分享给大家供大家参考。具体分析如下:

在C#中有两个属性,分别为Property和Attribute,两个的中文意思都有特性、属性之间,但是用法上却不一样,为了区别,本文暂把Property称为特性,把Attribute称为属性。

Attribute才是本文的主角,把它称为属性我觉得很恰当。属性的意思就是附属于某种事物上的,用来说明这个事物的各种特征的一种描述。而Attribute就是干这事的。它允许你将信息与你定义的C#类型相关联,作为类型的标注。这些信息是任意的,就是说,它不是由语言本身决定的,你可以随意建立和关联任何类型的任何信息。你可以作用属性定义设计时信息和运行时信息,甚至是运行时的行为特征。关键在于这些信息不仅可以被用户取出来作为一种类型的标注,它更可以被编译器所识别,作为编译时的一种附属条件参加程序的编译。

以下部分内容及代码来源于《C#技术揭秘》(Inside C# Sencond Edition)

定义属性:

属性实际上是一个派生自System.Attribute基类的类。System.Attribute类含有几个用于访问和检查自定义属性的方法。尽管你有权将任何类定义为属性,但是按照惯例来说,从System.Attribute派生类是有意义的。示例如下:

public enum RegHives
{
   HKEY_CLASSES_ROOT,
   HKEY_CURRENT_USER,
   HKEY_LOCAL_MACHINE,
   HKEY_USERS,
   HKEY_CURRENT_CONFIG
}
public class RegKeyAttribute : Attribute
{
   public RegKeyAttribute(RegHives Hive, String ValueName)
   {
    this.Hive = Hive;
    this.ValueName = ValueName;
   }
   protected RegHives hive;
   public RegHives Hive
   {
    get { return hive; }
    set { hive = value; }
   }
   protected String valueName;
   public String ValueName
   {
    get { return valueName; }
    set { valueName = value; }
   }
}

我们在这里添加了不同注册表的枚举、属性类的构造器以及两个特性(Property)。在定义属性时你可以做许许多多的事情,下面我们看看如何在运行时查询属性。要想在运行时查询类型或成员所附着的属性,必须使用反射

查询类属性:

假设你希望定义一个属性,这个属性定义了将在其上创建对象的远程服务器。如果没有这个属性,就要把此信息保存在一个常量中或是一个应用程序的资源文件中。通过使用属性,只需用以下方法标注出类的远程服务器名即可:

using System;
namespace QueryAttribs
{
  public enum RemoteServers
  {
   JEANVALJEAN,
   JAVERT,
   COSETTE
  }
  public class RemoteObjectAttribute : Attribute
  {
   public RemoteObjectAttribute(RemoteServers Server)
   {
    this.server = Server;
   }
   protected RemoteServers server;
   public string Server
   {
    get
    {
     return RemoteServers.GetName(
      typeof(RemoteServers), this.server);
    }
   }
  }
  [RemoteObject(RemoteServers.COSETTE)]
  class MyRemotableClass
  {
  }
  class Test
  {
   [STAThread]
   static void Main(string[] args)
   {
    Type type = typeof(MyRemotableClass);
    foreach (Attribute attr in
     type.GetCustomAttributes(true))
    {
     RemoteObjectAttribute remoteAttr =
      attr as RemoteObjectAttribute;
     if (null != remoteAttr)
     {
     Console.WriteLine(
       "Create this object on {0}.",
       remoteAttr.Server);
     }
    }
    Console.ReadLine();
   }
  }
}

运行结果为:

Creat this object on COSETTE。

注意:在这个例子中的属性类名具有Attribute后缀。但是,当我们将此属性附着给类型或成员时却不包括Attribute后缀。这是C#语言的设计者提供的简单方式。当编译器看到一个属性被附着给一个类型或成员时,它会搜索具有指定属性名的System.Attribute派生类。如果编译器没有找到匹配的类,它就在指定的属性名后面加上Attribute,然后再进行搜索。因此,常见的使用做法是将属性类名定义为以Attribute结尾,在使用时忽略名称的这一部分。以下的代码都采用这种命名方式。

查询方法属性:

在下面这个例子中,我们使用属性将方法定义为可事务化的方法,只要存在TransactionableAttribute属性,代码就知道具有这个属性的方法可以属于一个事务。

using System;
using System.Reflection;
namespace MethodAttribs
{
  public class TransactionableAttribute : Attribute
  {
   public TransactionableAttribute()
   {
   }
  }
  class SomeClass
  {
   [Transactionable]
   public void Foo()
   {}
   public void Bar()
   {}
   [Transactionable]
   public void Goo()
   {}
  }
  class Test
  {
   [STAThread]
   static void Main(string[] args)
   {
    Type type = Type.GetType("MethodAttribs.SomeClass");
    foreach (MethodInfo method in type.GetMethods())
    {
     foreach (Attribute attr in
      method.GetCustomAttributes(true))
     {
      if (attr is TransactionableAttribute)
      {
       Console.WriteLine(
        "{0} is transactionable.",
        method.Name);
      }
     }
    }
    Console.ReadLine();
   }
  }
}

运行结果如下:

Foo is transactionable.
Goo is transactionable.
 
查询字段属性:

假设有一个类含有一些字段,我们希望将它们的值保存进注册表。为此,可以使用以枚举值和字符串为参数的构造器定义一个属性,这个枚举值代表正确的注册表hive,字符串代表注册表值名称。在运行时可以查询字段的注册表键。

using System;
using System.Reflection;
namespace FieldAttribs
{
  public enum RegHives
  {
   HKEY_CLASSES_ROOT,
   HKEY_CURRENT_USER,
   HKEY_LOCAL_MACHINE,
   HKEY_USERS,
   HKEY_CURRENT_CONFIG
  }
  public class RegKeyAttribute : Attribute
  {
   public RegKeyAttribute(RegHives Hive, String ValueName)
   {
    this.Hive = Hive;
    this.ValueName = ValueName;
   }
   protected RegHives hive;
   public RegHives Hive
   {
    get { return hive; }
    set { hive = value; }
   }
   protected String valueName;
   public String ValueName
   {
    get { return valueName; }
    set { valueName = value; }
   }
  }
  class SomeClass
  {
   [RegKey(RegHives.HKEY_CURRENT_USER, "Foo")]
   public int Foo;

   public int Bar;
  }
  class Test
  {
   [STAThread]
   static void Main(string[] args)
   {
    Type type = Type.GetType("FieldAttribs.SomeClass");
    foreach (FieldInfo field in type.GetFields())
    {
     foreach (Attribute attr in
      field.GetCustomAttributes(true))
     {
      RegKeyAttribute rka =
       attr as RegKeyAttribute;
      if (null != rka)
      {
       Console.WriteLine(
        "{0} will be saved in"
        + " {1}\\\\{2}",
        field.Name,
        rka.Hive,
        rka.ValueName);
      }
     }
    }
    Console.ReadLine();
   }
  }
}

运行结果为:

Foo will be saved in HKEY_CURRENT_USER\\Foo

大家可以看到,用属性来标注类、方法、字段,既可以把用户的自定义信息附属在实体上,又可以在运行时动态的查询。下面我将讲一些C#中默认的预定义属性,见下表:

预定义的属性 有效目标 说明
AttributeUsage Class 指定另一个属性类的有效使用方式
CLSCompliant 全部 指出程序元素是否与CLS兼容
Conditional Method 指出如果没有定义相关联的字符串,编译器就可以忽略对这个方法的任何调用
DllImport Method 指定包含外部方法的实现的DLL位置
STAThread Method(Main) 指出程序的默认线程模型为STA
MTAThread Method(Main) 指出程序的默认模型为多线程(MTA)
Obsolete 除了Assembly、Module、Parameter和Return 将一个元素标示为不可用,通知用户此元素将被从未来的产品
ParamArray Parameter 允许单个参数被隐式地当作params(数组)参数对待
Serializable Class、Struct、enum、delegate 指定这种类型的所有公共和私有字段可以被串行化
NonSerialized Field 应用于被标示为可串行化的类的字段,指出这些字段将不可被串行化
StructLayout Class、struct 指定类或结构的数据布局的性质,比如Auto、Explicit或sequential
ThreadStatic Field(静态) 实现线程局部存储(TLS)。不能跨多个线程共享给定的静态字段,每个线程拥有这个静态字段的副本

下面介绍几种常用的属性

1.[STAThread]和[MTAThread]属性

class Class1
{
  [STAThread]
  Static void Main( string[] args )
  {
  }
}

使用STAThread属性将程序的默认线程模型指定为单线程模型。注意,线程模型只影响使用COM interop的应用程序,将这个属性应用于不使用COM interop的程序将不会产生任何效果。

2. AttributeUsage属性

除了用于标注常规C#类型的自定义属性以外,还可以使用AttributeUsage属性定义你使用这些属性的方式。文件记录的AttributeUsage属性调用用法如下:

[AttributeUsage( validon , AllowMutiple = allowmutiple , Inherited = inherited )]
Validon参数是AttributeTargets类型的,这个枚举值的定义如下:
public enum AttributeTargets
{
  Assembly = 0x0001,
  Module = 0x0002,
  Class = 0x0004,
  Struct = 0x0008,
  Enum = 0x0010,
  Constructor = 0x0020,
  Method = 0x0040,
  Property = 0x0080,
  Field = 0x0100,
  Event = 0x200,
  Interface = 0x400,
  Parameter = 0x800,
  Delegate = 0x1000,
  All = Assembly | Module | Class | Struct | Enum | Constructor| Method | Property|     Filed| Event| Interface | Parameter | Deleagte ,
  ClassMembers = | Class | Struct | Enum | Constructor | Method | Property | Field |     Event | Delegate | Interface
}

AllowMultiple决定了可以在单个字段上使用某个属性多少次,在默认情况下,所有的属性都是单次使用的。示例如下:

[AttributeUsage( AttributeTargets.All , AllowMultiple = true )]
public class SomethingAttribute : Attribute
{
  public SomethingAttribute( string str )
  {
  }
}
//如果AllowMultiple = false , 此处会报错
[Something(“abc”)]
[Something(“def”)]
class Myclass
{
}

Inherited参数是继承的标志,它指出属性是否可以被继承。默认是false。
Inherited AllowMultiple 结果
true false 派生的属性覆盖基属性
true false 派生的属性和基属性共存

代码示例:

using System;
using System.Reflection;
namespace AttribInheritance
{
  [AttributeUsage(
   AttributeTargets.All,
   AllowMultiple=true,
//  AllowMultiple=false,
   Inherited=true
  )]
  public class SomethingAttribute : Attribute
  {
   private string name;
   public string Name
   {
    get { return name; }
    set { name = value; }
   }
   public SomethingAttribute(string str)
   {
    this.name = str;
   }
  }
  [Something("abc")]
  class MyClass
  {
  }
  [Something("def")]
  class Another : MyClass
  {
  }
  class Test
  {
   [STAThread]
   static void Main(string[] args)
   {
    Type type =
     Type.GetType("AttribInheritance.Another");
    foreach (Attribute attr in
     type.GetCustomAttributes(true))
//    type.GetCustomAttributes(false))
    {
     SomethingAttribute sa =
      attr as SomethingAttribute;
     if (null != sa)
     {
     Console.WriteLine(
       "Custom Attribute: {0}",
       sa.Name);
     }
    }

   }
  }
}

当AllowMultiple被设置为false时,结果为:
Custom Attribute : def
当AllowMultiple被设置为true时,结果为:
Custom Attribute : def
Custom Attribute : abc

注意,如果将false传递给GetCustomAttributes,它不会搜索继承树,所以你只能得到派生的类属性。
 
3.Conditional 属性

你可以将这个属性附着于方法,这样当编译器遇到对这个方法调用时,如果没有定义对应的字符串值,编译器就忽略这个调用。例如,以下方法是否被编译取决于是否定义了字符串“DEGUG”:

[Condition(“DEBUG”) ]
public void SomeDebugFunc()
{
  Console.WriteLine(“SomeDebugFunc”);
}
using System;
using System.Diagnostics;
namespace CondAttrib
{
  class Thing
  {
   private string name;
   public Thing(string name)
   {
    this.name = name;
    #if DEBUG
     SomeDebugFunc();
    #else
     SomeFunc();
    #endif
   }
   public void SomeFunc()
    { Console.WriteLine("SomeFunc"); }
   [Conditional("DEBUG")]
   [Conditional("ANDREW")]
   public void SomeDebugFunc()
    { Console.WriteLine("SomeDebugFunc"); }
  }
  public class Class1
  {
   [STAThread]
   static void Main(string[] args)
   {
    Thing t = new Thing("T1");
   }
  }
}

4. Obsolete 属性

随着代码不断的发展,你很可以会有一些方法不用。可以将它们都删除,但是有时给它们加上适当的标注比删除它们更合适,例如:

using System;
namespace ObsAttrib
{
  class SomeClass
  {
   [Obsolete("Don't use OldFunc, use NewFunc instead", true)]
   public void OldFunc( ) { Console.WriteLine("Oops"); }

   public void NewFunc( ) { Console.WriteLine("Cool"); }
  }
  class Class1
  {
   [STAThread]
   static void Main(string[] args)
   {
    SomeClass sc = new SomeClass();
    sc.NewFunc();
//   sc.OldFunc(); // compiler error
   }
  }
}

我们将Obsolete属性的第二个参数设置为true,当调用时函数时编译器会产生一个错误。

E:\InsideC#\Code\Chap06\ObsAttrib\ObsAttrib\Class1.cs(20): 'ObsAttrib.SomeClass.OldFunc()' 已过时: 'Don't use OldFunc, use NewFunc instead'
 
5. DllImport和StructLayout属性

DllImport可以让C#代码调用本机代码中的函数,C#代码通过平台调用(platform invoke)这个运行时功能调用它们。

如果你希望运行时环境将结构从托管代码正确地编组现非托管代码(或相反),那么需要为结构的声明附加属性。为了使结构参数可以被正确的编组,必须使用StructLayout属性声明它们,指出数据应该严格地按照声明中列出的样子进行布局。如果不这么做,数据将不能正确地被编组,而应用程序可能会出错。

using System;
using System.Runtime.InteropServices; // for DllImport
namespace nativeDLL
{
  public class Test
  {
//  [DllImport ("user32.dll")] // all the defaults are OK
   [DllImport("user32", EntryPoint="MessageBoxA",
    SetLastError=true,
    CharSet=CharSet.Ansi, ExactSpelling=true,
    CallingConvention=CallingConvention.StdCall)]
   public static extern int MessageBoxA (
    int h, string m, string c, int type);
   [StructLayout(LayoutKind.Sequential)]
   public class SystemTime {
    public ushort wYear;
    public ushort wMonth;
    public ushort wDayOfWeek;
    public ushort wDay;
    public ushort wHour;
    public ushort wMinute;
    public ushort wSecond;
    public ushort wMilliseconds;
   }
   [DllImport ("kernel32.dll")]
   public static extern void GetLocalTime(SystemTime st);
   [STAThread]
   public static void Main(string[] args)
   {
    MessageBoxA(0, "Hello World", "nativeDLL", 0);
    SystemTime st = new SystemTime();
    GetLocalTime(st);
    string s = String.Format("date: {0}-{1}-{2}",
     st.wMonth, st.wDay, st.wYear);
    string t = String.Format("time: {0}:{1}:{2}",
     st.wHour, st.wMinute, st.wSecond);
    string u = s + ", " + t;
    MessageBoxA(0, u, "Now", 0);
   }
  }
}

6. 配件属性

当使用.NET产生任何类型的C#工程时,会自动的产生一个AssemblyInfo.cs源代码文件以及应用程序源代码文件。AssemblyInfo.cs中含有配件中代码的信息。其中的一些信息纯粹是信息,而其它信息使运行时环境可以确保惟一的命名和版本号,以供重用你的配件的客户代码使用。
 
7. 上下文属性

.NET柜架还提供了另一种属性:上下文属性。上下文属性提供了一种截取机制,可以在类的实例化和方法调用之前和之后进行处理。这种功能用于对象远程调用,它是从基于COM的系统所用的COM+组件服务和Microsoft Transaction Services(MTS)。

希望本文所述对大家的C#程序设计有所帮助。

(0)

相关推荐

  • C#反射的一些应用

    对于反射贫道也是很陌生的,所以趁现在有时间就把反射看了一下,记下笔记!!!反射的定义:反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的名称.限定符和参数等.有了反射,即可对每一个类型了如指掌.如果获得了构造函数的信息,即可直接创建对象,即使这个对象的类型在编译时还不知道.  1,导入using System.Reflection;  2,Asse

  • C#泛型和反射实例解析

    C#中的泛型和反射经常是一起工作的,因此这里就一次性的加以介绍了. 由于c#是强类型语言,一般来说函数的返回类型和参数的类型都是一早写好的,这也就造成了很多时候不像js那样方便使用,不够灵话. 因此就有了这个泛型,它可以让你的函数和参数在调用的时候才决定类型.如下例所示: public T abc<T>(T word) { return word; return default(T); //关键字default可以对引用类型返回nullAble,int类型返回0,初始化一个T的感觉啦 } ab

  • C#基础学习系列之Attribute和反射详解

    前言 本文主要给大家介绍了关于C#基础之Attribute和反射的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. Attribute(特性) Attribute是C#的一种语言特性,用于为各种实体(class,field,property)附加一些说明性信息, 并且可以在运行时环境中检索这些信息(通过反射). 所有的Attribute必须继承自Attribute类,按照约定,特性类的名称带有 Attribute 后缀.使用特性时可以包含或省略此后缀. Attribut

  • 关于C#基础知识回顾--反射(一)

    反射(reflection)是一种允许用户获得类型信息的C#特性.术语"反射"源自于它的工作方式:Type对象映射它所代表的底层对象.对Type对象进行查询可以获得(反射)与类型相关的信息.反射是一种功能强大的机制,它允许学习和使用只在运行时才能知道的类型功能. 这些是官方定义,其实说白了,反射就是能知道我们未知类型的类型信息这么一个东西.没什么神秘可讲!反射的核心是System.Type.System.Type包含了很多属性和方法,使用这些属性和方法可以在运行时得到类型信息.一旦得到

  • c#反射调用方法示例

    获取方法的相关信息的两种形式 反射是一种允许用户获得类信息的C#功能,Type对象映射它代表的底层对象: 在.Net 中, 一旦获得了Type对象,就可以使用GetMethods()方法获取此类型支持的方法列表:该方法的两种形式: MethodInfo [] GetMethods() MethodInfo [] GetMethods(BindingFlags bindingflas)  :它的参数带有一些限制 BindingFlags  是一个枚举 枚举成员 [DeclaredOnly,Inst

  • C#反射实例学习及注意内容

    C#反射的入门学习首先要明白C#反射提供了封装程序集.模块和类型的对象等等.那么这样可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性.如果代码中使用了属性,可以利用反射对它们进行访问. MSDN描述: 反射通常具有以下用途: 使用 Assembly 定义和加载程序集,加载在程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例. 使用 Module 发现以下信息:包含模块的程序集以及模块中的类等.您还可以获取在模块上定义的所有全

  • C#中的程序集和反射介绍

    什么是程序集? 1.程序集(assembly)是一个及一个以上托管模块,以及一些资源文件的逻辑组合. 2.程序集是组件复用,以及实施安全策略和版本策略的最小单位. 3.程序集是包含一个或者多个类型定义文件和资源文件的集合.在程序集包含的所有文件中,有一个文件用于保存清单.(清单是元数据部分中一组数据表的集合,其中包含了程序集中一部分文件的名称,描述了程序集的版本,语言文化,发布者,共有导出类型,以及组成该程序集的所有文件). 4.在编译应用程序中,所创建的CIL代码存储在一个程序集中,程序集包括

  • C#属性(Attribute)用法实例解析

    属性(Attribute)是C#程序设计中非常重要的一个技术,应用范围广泛,用法灵活多变.本文就以实例形式分析了C#中属性的应用.具体入戏: 一.运用范围 程序集,模块,类型(类,结构,枚举,接口,委托),字段,方法(含构造),方法,参数,方法返回值,属性(property),Attribute [AttributeUsage(AttributeTargets.All)] public class TestAttribute : Attribute { } [TestAttribute]//结构

  • C#中Property和Attribute的区别实例详解

    本文实例分析了C#中Property和Attribute的区别.分享给大家供大家参考.具体分析如下: 在C#中有两个属性,分别为Property和Attribute,两个的中文意思都有特性.属性之间,但是用法上却不一样,为了区别,本文暂把Property称为特性,把Attribute称为属性. Attribute才是本文的主角,把它称为属性我觉得很恰当.属性的意思就是附属于某种事物上的,用来说明这个事物的各种特征的一种描述.而Attribute就是干这事的.它允许你将信息与你定义的C#类型相关联

  • C++ 中引用与指针的区别实例详解

    C++ 中引用与指针的区别实例详解 引用是从C++才引入的,在C中不存在.为了搞清楚引用的概念,得先搞明白变量的定义及引用与变量的区别,变量的要素一共有两个:名称与空间. 引用不是变量,它仅仅是变量的别名,没有自己独立的空间,它只符合变量的"名称"这个要素,而"空间"这个要素并不满足.换句话说,引用需要与它所引用的变量共享同一个内存空间,对引用所做的改变实际上是对所引用的变量做出修改.并且引用在定义的时候就必须被初始化.     参数传递的类型及相关要点: 1 按值

  • C++ 中cerr和cout的区别实例详解

    C++ 中cerr和cout的区别实例详解 前言: cerrThe object controls unbuffered insertions to the standard error output as a byte stream. Once the object is nstructed, the expression cerr.flags & unitbuf is nonzero. Example // iostream_cerr.cpp // compile with: /EHsc /

  • java中 String和StringBuffer的区别实例详解

    java中 String和StringBuffer的区别实例详解 String: 是对象不是原始类型.            为不可变对象,一旦被创建,就不能修改它的值.            对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.            String 是final类,即不能被继承. StringBuffer: 是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象            它只能通过构造函数来建立,  

  • Android MotionEvent中getX()和getRawX()的区别实例详解

    Android MotionEvent中getX()和getRawX()的区别实例详解 实例代码: public class Res extends Activity implements View.OnTouchListener { Button btn = null; int x = 0; int y = 0; int rawx = 0; int rawy = 0; @Override public void onCreate(Bundle savedInstanceState) { sup

  • Angular中ng-bind和ng-model的区别实例详解

    ng-bind和ng-model的区别 AngularJS的数据绑定有ng-bind和ng-model,一般用于如下: <input ng-model="object.xxx"> <span ng-bind="object.xxx"></span> ng-bind是单向绑定,由作用于$scope到view层,且在HTML控件(HTML控件有:input.select.button和textarea)中不可显示. ng-model是

  • Android 中SP与DP的区别实例详解

    从一开始写Android程序,就被告知这些常识 1.长度宽度的数值要使用dp作为单位放入dimens.xml文件中 2.字体大小的数值要使用sp作为单位,也放入dimens.xml文件中 然后,就没有然后了,仿佛潜台词就是说,你记住去用就行了. 偶然有一天,当我们阴差阳错地将字体写成了dp,也是可以工作,而且效果和sp一样. 这时候,就开始怀疑了,到底有啥区别呢,dp和sp有什么不同呢? 我们做个简单的Sample验证一下,如下,一个布局代码 <TextView android:layout_w

  • Mysql中where与having的区别实例详解

    以一道题来做引子 牛客,SQL30 计算总和 OrderItems表代表订单信息,包括字段:订单号order_num和item_price商品售出价格.quantity商品数量. order_num item_price quantity a1 10 105 a2 1 1100 a3 1 200 a4 2 1121 a5 5 10 a6 1 19 a7 7 5 [问题]编写 SQL 语句,根据订单号聚合,返回订单总价不小于1000 的所有订单号,最后的结果按订单号进行升序排序. 提示:总价 =

  • jQuery中的on与bind绑定事件区别实例详解

    on(events,[selector],[data],fn) events:一个或多个用空格分隔的事件类型和可选的命名空间,如"click"或"keydown.myPlugin" . selector:一个选择器字符串用于过滤器的触发事件的选择器元素的后代. data:当一个事件被触发时要传递event.data给事件处理函数. fn:该事件被触发时执行的函数. false 值也可以做一个函数的简写,返回false. bind(type,[data],fn) 为每

  • jQuery中text() val()和html()的区别实例详解

    简单的说:html()和text()的区别主要在于是否包含标签.而val()针对的是表单元素. 但是有时还是不是那么太清晰. html(),val(),text()都分为有参和无参. 举例说明它们的不同之处: html()在没有参数的情况下,取得第一个匹配元素的内容.必须要注意的是,即使匹配多个,也只能取得匹配的第一个元素. 如: <body> <p>你选中这段文字后,看看它们的文本颜色和背景色,就能明白::selection的作用.</p> <h3>选中下

随机推荐