C#里的"特性"(Attribute)也太不讲理了吧!

CsToD 2009-08-31 01:30:36
很早以前就觉得特性的行为很奇怪,例如DllImport("..."),按常理来说,需要一个字符串,那我给你一个就行了,但这里只能是常量,而不能是变量,例如可以是:
DllImport("user32")
或者
const string str="user32";
DllImport(str)

但下面却不行:
static string str="user32";
DllImport(str)


最近又发现一个更奇怪的:
    [System.Runtime.InteropServices.Guid("ok")]
class My
{
}

编译器居然报错,说格式不正确!!!

通常来说,编译器只检查类型,而不检查值,所以就算是格式不对,也是“运行时异常”,凭什么编译器就能检查出来?

于是看了下GuidAttribute的源代码,没发现什么特别之处,于是我将源代码复制出来,并应用到类里面,郁闷地是,现在编译器居然又不报错了!!!

namespace Myself
{
[AttributeUsage(AttributeTargets.Delegate | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Assembly, Inherited = false), ComVisible(true)]
public sealed class GuidAttribute : Attribute
{
// Fields
internal string _val;

// Methods
public GuidAttribute(string guid)
{
this._val = guid;
}

// Properties
public string Value
{
get
{
return this._val;
}
}
}
}
[Myself.Guid("OK")]
class You
{
}


同样的代码,系统的检查,自己的却不检查,这也太不讲理了吧?
...全文
317 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
Dobzhansky 2009-09-01
  • 打赏
  • 举报
回复
唉, 同样是 C# 编译器, CodeDom 那个就没这个本事了

new Microsoft.CSharp.CSharpCodeProvider();// 这个不行
mengsijun1987 2009-09-01
  • 打赏
  • 举报
回复
up
Dobzhansky 2009-09-01
  • 打赏
  • 举报
回复
经测试:
同样的接口, 用 C++/CLI 语言写出来, 编译就没有警告,
可见 C# 编译器的强大, 速度还这么快.
Dobzhansky 2009-09-01
  • 打赏
  • 举报
回复
也不是合法的 guid 就可以用的,

试看:

[ComVisible(true)]
[Guid("00000000-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface Interface1
{
int hello();
}


编译, 警告了:
[Quote="warning"]
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets : warning : Type 'Interface1' has an IID of IID_IUnknown or IID_IDispatch, which is not allowed.
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets : warning : Type 'Interface1' has an IID of IID_IUnknown or IID_IDispatch, which is not allowed.

[/Quote]

哪些是合法的 guid, 谁说了算, 是编译器吧? 看来是编译器给检测, 因此这个检测发生在调用构造函数之前
CsToD 2009-09-01
  • 打赏
  • 举报
回复
up
lovelan1748 2009-08-31
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 chrisak 的回复:]
刚查了一遍MSDN...是我对属性的存储方式理解有误
这样看来的话应该是C#编译器特别对Guid进行了检查了吧.
[/Quote]
ChrisAK 2009-08-31
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 lovelan1748 的回复:]
引用 7 楼 chrisak 的回复:
引用 5 楼 cstod 的回复:
引用 3 楼 chrisak 的回复:
Guid ("ok");
LZ你很有才...头一次见到这种GUID.建议你先去了解下什么叫Guid.


这就叫回贴不看贴......

我本来就是“故意”“构造”错误的,纯属语法分析
属性是序列化后存储在程序集中的.你使用[Guid("ok")]给一个类添加属性的时候,编译器会调用GuidAttribute类的构造函数,而GuidAttribute会试着用你传入的参数去构造一个Guid."ok"不是一个合法
的Guid.当然报错咯.

于是看了下GuidAttribute的源代码,没发现什么特别之处,于是我将源代码复制出来,并应用到类里面,郁闷地是,现在编译器居然又不报错了!!!
-------楼主的原话,别把问题扯远了
[/Quote]刚查了一遍MSDN...是我对属性的存储方式理解有误
这样看来的话应该是C#编译器特别对Guid进行了检查了吧.
lovelan1748 2009-08-31
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 chrisak 的回复:]
引用 5 楼 cstod 的回复:
引用 3 楼 chrisak 的回复:
Guid ("ok");
LZ你很有才...头一次见到这种GUID.建议你先去了解下什么叫Guid.


这就叫回贴不看贴......

我本来就是“故意”“构造”错误的,纯属语法分析
属性是序列化后存储在程序集中的.你使用[Guid("ok")]给一个类添加属性的时候,编译器会调用GuidAttribute类的构造函数,而GuidAttribute会试着用你传入的参数去构造一个Guid."ok"不是一个合法
的Guid.当然报错咯.
[/Quote]
于是看了下GuidAttribute的源代码,没发现什么特别之处,于是我将源代码复制出来,并应用到类里面,郁闷地是,现在编译器居然又不报错了!!!
-------楼主的原话,别把问题扯远了
ChrisAK 2009-08-31
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 cstod 的回复:]
引用 3 楼 chrisak 的回复:
Guid ("ok");
LZ你很有才...头一次见到这种GUID.建议你先去了解下什么叫Guid.


这就叫回贴不看贴......

我本来就是“故意”“构造”错误的,纯属语法分析
[/Quote]属性是序列化后存储在程序集中的.你使用[Guid("ok")]给一个类添加属性的时候,编译器会调用GuidAttribute类的构造函数,而GuidAttribute会试着用你传入的参数去构造一个Guid."ok"不是一个合法
的Guid.当然报错咯.
guoyichao 2009-08-31
  • 打赏
  • 举报
回复
vs编译器针对一些特定的attribute做了些特殊处理,换用sharpdevelop编译试试。
CsToD 2009-08-31
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 chrisak 的回复:]
Guid ("ok");
LZ你很有才...头一次见到这种GUID.建议你先去了解下什么叫Guid.
[/Quote]

这就叫回贴不看贴......

我本来就是“故意”“构造”错误的,纯属语法分析
我姓区不姓区 2009-08-31
  • 打赏
  • 举报
回复
没有办法,人家就是有特权
ChrisAK 2009-08-31
  • 打赏
  • 举报
回复
Guid ("ok");
LZ你很有才...头一次见到这种GUID.建议你先去了解下什么叫Guid.
soaringbird 2009-08-31
  • 打赏
  • 举报
回复
属性,主要还是用在编译上的
lovelan1748 2009-08-31
  • 打赏
  • 举报
回复
反射学习中,暂时无能力深究这些,帮顶

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧