.net 如何将GUID作为属性参数?
我在某些属性类中需要Guid属性,如下所示:.net 如何将GUID作为属性参数?,.net,attributes,guid,.net,Attributes,Guid,我在某些属性类中需要Guid属性,如下所示: public class SomeAttribute : Attribute { private Guid foreignIdentificator; public Guid ForeignIdentificator { get { return this.foreignIdentificator; } set { this.foreignIdentificator = value; } } }
public class SomeAttribute : Attribute {
private Guid foreignIdentificator;
public Guid ForeignIdentificator {
get { return this.foreignIdentificator; }
set { this.foreignIdentificator = value; }
}
}
但在属性定义中,我只能使用原语类型,它们是常量(我理解原因,这让我有意义)。解决方法可以是将“ForeignIdentificator”定义为字符串,并在运行时创建Guid:
public class SomeAttribute : Attribute {
private string foreignIdentificator;
public string ForeignIdentificator {
get { return this.foreignIdentificator; }
set { this.foreignIdentificator = value; }
}
public Guid ForeignIdentificatorGuid {
get { return new Guid( ForeignIdentificator ); }
}
}
未及时检查类型安全性。“ForeignIdentificator”属性可以包含任何字符串值,并且在创建Guid期间,将在运行时而不是编译时引发异常
我知道编译器会检查字符串值“System.Runtime.InteropServices.GuidAttribute”的“Guid兼容性”。这个检查正是我需要的,但我不知道这个检查是在编译器中硬编码的还是可以显式定义的(以及如何定义)
您知道如何保护属性的“Guid兼容性”检查吗?或者另一种方式,如何在属性中实现类型安全的Guid定义?
谢谢。我以前遇到过你的问题。我们只是要求它们以字符串形式传入GUID。。。VS GUID生成器工具提供给我们的默认方式(*F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4)。我们基本上做了你做的事。我们在插件体系结构中使用它,因此我们的客户一直是使用该接口的人。如果你看看微软在需要做同样的事情时做了什么,他们也会这么做 这样做不成问题。我们从未将此视为现场问题 不过,您可能希望将该字符串字段命名为GUID,以免混淆您的使用者。添加一些文档,以防他们不知道它需要什么格式
当我看到这个的时候我也有同样的反应。。。但接下来我继续,因为似乎没有类型安全的解决方案。属性参数必须是常量。如果我违反了规则,我的C#编译器会给出以下错误: 属性参数必须是常量表达式、typeof表达式或属性参数类型的数组创建表达式 由于C#中没有GUID文本,因此必须用另一种格式(例如字符串)对GUID进行编码。但是,您并不是完全不知所措:您可以使属性具有一个采用所需格式的ctor。下面是一个与
System.Guid
具有相同系数的示例:
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
sealed class MyGuidAttribute : Attribute
{
public Guid Guid { get; private set; }
//
// Summary:
// Initializes a new instance of the System.Guid class using the specified array
// of bytes.
//
// Parameters:
// b:
// A 16 element byte array containing values with which to initialize the GUID.
//
// Exceptions:
// System.ArgumentNullException:
// b is null.
//
// System.ArgumentException:
// b is not 16 bytes long.
public MyGuidAttribute(byte[] b)
{
this.Guid = new Guid(b);
}
//
// Summary:
// Initializes a new instance of the System.Guid class using the value represented
// by the specified string.
//
// Parameters:
// g:
// A System.String that contains a GUID in one of the following formats ('d'
// represents a hexadecimal digit whose case is ignored): 32 contiguous digits:
// dddddddddddddddddddddddddddddddd -or- Groups of 8, 4, 4, 4, and 12 digits
// with hyphens between the groups. The entire GUID can optionally be enclosed
// in matching braces or parentheses: dddddddd-dddd-dddd-dddd-dddddddddddd -or-
// {dddddddd-dddd-dddd-dddd-dddddddddddd} -or- (dddddddd-dddd-dddd-dddd-dddddddddddd)
// -or- Groups of 8, 4, and 4 digits, and a subset of eight groups of 2 digits,
// with each group prefixed by "0x" or "0X", and separated by commas. The entire
// GUID, as well as the subset, is enclosed in matching braces: {0xdddddddd,
// 0xdddd, 0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}} All braces, commas,
// and "0x" prefixes are required. All embedded spaces are ignored. All leading
// zeroes in a group are ignored. The digits shown in a group are the maximum
// number of meaningful digits that can appear in that group. You can specify
// from 1 to the number of digits shown for a group. The specified digits are
// assumed to be the low order digits of the group.
//
// Exceptions:
// System.ArgumentNullException:
// g is null.
//
// System.FormatException:
// The format of g is invalid.
//
// System.OverflowException:
// The format of g is invalid.
public MyGuidAttribute(string g)
{
this.Guid = new Guid(g);
}
//
// Summary:
// Initializes a new instance of the System.Guid class using the specified integers
// and byte array.
//
// Parameters:
// a:
// The first 4 bytes of the GUID.
//
// b:
// The next 2 bytes of the GUID.
//
// c:
// The next 2 bytes of the GUID.
//
// d:
// The remaining 8 bytes of the GUID.
//
// Exceptions:
// System.ArgumentNullException:
// d is null.
//
// System.ArgumentException:
// d is not 8 bytes long.
public MyGuidAttribute(int a, short b, short c, byte[] d)
{
this.Guid = new Guid(a, b, c, d);
}
//
// Summary:
// Initializes a new instance of the System.Guid class using the specified integers
// and bytes.
//
// Parameters:
// a:
// The first 4 bytes of the GUID.
//
// b:
// The next 2 bytes of the GUID.
//
// c:
// The next 2 bytes of the GUID.
//
// d:
// The next byte of the GUID.
//
// e:
// The next byte of the GUID.
//
// f:
// The next byte of the GUID.
//
// g:
// The next byte of the GUID.
//
// h:
// The next byte of the GUID.
//
// i:
// The next byte of the GUID.
//
// j:
// The next byte of the GUID.
//
// k:
// The next byte of the GUID.
public MyGuidAttribute(int a, short b, short c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k)
{
this.Guid = new Guid(a, b, c, d, e, f, g, h, i, j, k);
}
//
// Summary:
// Initializes a new instance of the System.Guid class using the specified unsigned
// integers and bytes.
//
// Parameters:
// a:
// The first 4 bytes of the GUID.
//
// b:
// The next 2 bytes of the GUID.
//
// c:
// The next 2 bytes of the GUID.
//
// d:
// The next byte of the GUID.
//
// e:
// The next byte of the GUID.
//
// f:
// The next byte of the GUID.
//
// g:
// The next byte of the GUID.
//
// h:
// The next byte of the GUID.
//
// i:
// The next byte of the GUID.
//
// j:
// The next byte of the GUID.
//
// k:
// The next byte of the GUID.
[CLSCompliant(false)]
public MyGuidAttribute(uint a, ushort b, ushort c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k)
{
this.Guid = new Guid(a, b, c, d, e, f, g, h, i, j, k);
}
}
“ForeignIdentificator”是在另一个程序集或数据库或其他任何地方定义的GUID值,应该在其中添加属性所有者。这听起来像布什主义。编写新GUID对我来说不是问题(我有一个密钥shourcut),但我担心其他人。但如果没有办法,如何在编译时确保正确的格式(恐怕没有),我必须创建实用程序,它将测试编译程序集中的所有属性定义。我理解您的担忧。我们也花了一些时间想弄明白。在微软的实现中,他们做同样的事情,所以我们放弃了。同样,我们担心这会成为实地的一个问题,但它一次也没有成为一个问题。一定要抓住你这边的例外,你证实了我的猜测。我将不再寻找其他解决方案。谢谢,你说得对。我也使用字符串将guid传递给属性。