I'm trying to do some serialization / deserialization stuff with a custom exception type. This type has a field defined as:
private object[] resourceMessageParams;
I've got all nice and strongly typed code with some Linq expression magic, but I want to go even further than that and do something like this:
using ResourceMessageParamsType = object[];//<-- "Identifier expected" error here
/*.开发者_如何学Python..*/
private ResourceMessageParamsType resourceMessageParams;
/*...*/
this.resourceMessageParams =
(ResourceMessageParamsType)serializationInfo.GetValue(
ReflectionHelper.GetPropertyNameFromExpression(() =>
resourceMessageParams), typeof(ResourceMessageParamsType));
Instead of this:
(object[])serializationInfo.GetValue(
ReflectionHelper.GetPropertyNameFromExpression(() =>
resourceMessageParams), typeof(object[]));
To accomodate for possible change of type of this field in the future, so one will have to change the type only once in alias definition. However, the compiler stops at object
in using ResourceMessageType = object[];
complaining that an identifier is expected. Changing to Object[]
helps somewhat, but this time the bracket is highlighted with the same error message.
Is there a way to define an alias for array type in c#?
You could define a class (or struct) called ResourceMessageParamsType and define implicit operators for casting to and from object[].
struct ResourceMessageParamsType
{
private object[] value;
private ResourceMessageParamsType(object[] value)
{
this.value = value;
}
public static implicit operator object[](ResourceMessageParamsType t)
{
return t.value;
}
public static implicit operator ResourceMessageParamsType(object[] value)
{
return new ResourceMessageParamsType(value);
}
}
Simply put, you can't "alias" array types.
You can work around it by encapsulating things in a struct
, but that doesn't answer your question.
Update:
From the ECMA standard,
using-alias-directive:
using
identifier = namespace-or-type-name ;
which clearly doesn't say anything about arrays being permitted.
(See page 100 for how namespace-or-type-name is defined.)
I would just derive my type from System.Array. If I'm interpreting this correctly What you are describing is a non-OO approach like you would use in plain C.
Update- I guess you can't subclass System.Array. Maybe there is a way around it.
using ResourceMessageParamsType = System.Array;
Not that I pretend to understand how this "safeguard[s] serialization code against possible changes in class definition" for you.
Interfaces would be a cleaner approach, and have you considered generics?
IMO Comprehensive Unit tests will ensure that if someone changes the aliased type, that all deserialization code still works.
Wrapping in a managed struct
as user541686 rightly mentions, creates another level of indirection to what is ultimately still a managed array. You can alternatively use a fixed
buffer in an unsafe struct
to have it allocated all-in-one under your preferred typename:
public unsafe struct MyPreferredTypeName
{
public fixed int buffer[256];
//Further dereferencing not req'd: this memory is allocated inline in the struct.
}
However you then have no choice but to use unsafe
blocks in your code that uses the struct
(and if I recall correctly, also fixed
blocks depending on your version of C#, I think < 9.0).
public void MyMethod(MyPreferredTypeName data) //you can alternatively use unsafe in this line
{
unsafe
{
fixed (MyPreferredTypeName* dataPtr = data)
{
dataPtr[6] = 79; //etc
}
}
}
精彩评论