Невозможно сделать это в настоящее время, используя язык как есть.Это можно сделать, и у меня есть два способа.
Первый - запустить сборку вывода через ILDASM, выполнить регулярное преобразование в объявление метода, которое вы хотите, изменить «public» на «family» в нужном вам методе.потом ИЛАСМ вернись.Ewwwww.
Второй, который я исследую, состоит в том, чтобы пометить методы с помощью
[<Protected>]
, а затем написать фильтр с помощью CCI , чтобы изменить доступность для всехметоды, которые имеют ProtectedAttribute и затем удаляют атрибут.Это выглядит менее неприлично, чем использование регулярных выражений над файлом, но мои настройки безопасности на работе серьезно ненавидят исходный код проекта CCI, поэтому я не могу успешно извлечь / распаковать / собрать его.
РЕДАКТИРОВАТЬ - вот мое решение- Я попробовал CCI, но он не готов к выполнению задачи.В итоге я использовал Cecil и получил следующий код:
Сначала атрибут в F #
open System
[<AttributeUsage(AttributeTargets.Method ||| AttributeTargets.Constructor, AllowMultiple=false, Inherited=true)>]
type MyProtectedAttribute() =
inherit System.Attribute()
, затем следующийприложение, которое является клиентом Cecil :
using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Text;
using Mono.Cecil;
using Mono.Collections.Generic;
using System.IO;
namespace AddProtectedAttribute
{
class Program
{
static void Main(string[] args)
{
if (args.Length != 1 || args.Length != 3)
{
Console.Error.WriteLine("Usage: AddProtectedAttribute assembly-file.dll /output output-file.dll");
return;
}
string outputFile = args.Length == 3 ? args[2] : null;
ModuleDefinition module = null;
try
{
module = ModuleDefinition.ReadModule(args[0]);
}
catch (Exception err)
{
Console.Error.WriteLine("Unable to read assembly " + args[0] + ": " + err.Message);
return;
}
foreach (TypeDefinition type in module.Types)
{
foreach (MethodDefinition method in type.Methods)
{
int attrIndex = attributeIndex(method.CustomAttributes);
if (attrIndex < 0)
continue;
method.CustomAttributes.RemoveAt(attrIndex);
if (method.IsPublic)
method.IsPublic = false;
if (method.IsPrivate)
method.IsPrivate = false;
method.IsFamily = true;
}
}
if (outputFile != null)
{
try
{
module.Write(outputFile);
}
catch (Exception err)
{
Console.Error.WriteLine("Unable to write to output file " + outputFile + ": " + err.Message);
return;
}
}
else
{
outputFile = Path.GetTempFileName();
try
{
module.Write(outputFile);
}
catch (Exception err)
{
Console.Error.WriteLine("Unable to write to output file " + outputFile + ": " + err.Message);
if (File.Exists(outputFile))
File.Delete(outputFile);
return;
}
try
{
File.Copy(outputFile, args[0]);
}
catch (Exception err)
{
Console.Error.WriteLine("Unable to copy over original file " + outputFile + ": " + err.Message);
return;
}
finally
{
if (File.Exists(outputFile))
File.Delete(outputFile);
}
}
}
static int attributeIndex(Collection<CustomAttribute> coll)
{
if (coll == null)
return -1;
for (int i = 0; i < coll.Count; i++)
{
CustomAttribute attr = coll[i];
if (attr.AttributeType.Name == "MyProtectedAttribute")
return i;
}
return -1;
}
}
}
и, наконец, украсьте методы, которые вы хотите защитить, с помощью MyProtectedAttribute и запустите приложение C # как шаг после сборки.