我尝试使用以下代码片段在内存中运行 C# 源生成器:
var syntaxTree = await SyntaxTreeFromRelativeFile("testdata/IMyInterface.cs");
var compilation = CSharpCompilation.Create("compilation", ImmutableArray.Create(syntaxTree), References);
var generator = new ProxyGenerator();
GeneratorDriver driver = CSharpGeneratorDriver.Create(generator);
driver = driver.RunGenerators(compilation);
Run Code Online (Sandbox Code Playgroud)
References设置为编译代码所需的源:
public static readonly ImmutableArray<MetadataReference> References = ImmutableArray.Create<MetadataReference>(
// System
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
MetadataReference.CreateFromFile(typeof(GCSettings).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Attribute).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location),
// JetBrains
MetadataReference.CreateFromFile(typeof(UsedImplicitlyAttribute).Assembly.Location),
// some custom ones
);
Run Code Online (Sandbox Code Playgroud)
虽然生成器以这种方式运行得很好,但遗憾的是它没有达到预期的效果,因为源生成器依赖于一个属性来知道是否为指定类型生成源。确切的来源如下:
[MyAttribute]
public interface IMyInterface { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
源生成器正确拾取属性,但它被解析为ExtendedErrorTypeSymbol结果类型为NotAnAttributeType。但是,扩展错误类型符号还有一个候选符号,这正是我期望它匹配的符号。
这让我感到惊讶,因为显然类型是一个属性,并且作为正常编译的一部分运行源生成器实际上确实生成了所有正确的类型。这似乎意味着由于这次运行的内存性质,发生了一些奇怪的事情。
据我所知,我的列表References涵盖了正确认识到某物是属性(mscorlib、System.Runtime、netstandard和System.Core)所需的所有内容,尽管也许还MetadataReference缺少另一个?
我确实发现了这个 …
我一直在使用MonoKickstart来获得在OSX上运行的项目 - 它是基于OpenTK构建的.我让程序完全正常工作,但是一旦我删除了我的Mono.framework(好吧,实际上已重命名),弹出以下错误:
[ERROR] FATAL UNHANDLED EXCEPTION: System.TypeInitializationException: An exception was thrown by the type initializer for System.Drawing.GDIPlus ---> System.DllNotFoundException: gdiplus.dll
at (wrapper managed-to-native) System.Drawing.GDIPlus:GdiplusStartup (ulong&,System.Drawing.GdiplusStartupInput&,System.Drawing.GdiplusStartupOutput&)
at System.Drawing.GDIPlus..cctor () [0x00000] in <filename unknown>:0
--- End of inner exception stack trace ---
at System.Drawing.Bitmap..ctor (System.String filename, Boolean useIcm) [0x00000] in <filename unknown>:0
at System.Drawing.Bitmap..ctor (System.String filename) [0x00000] in <filename unknown>:0
at (wrapper remoting-invoke-with-check) System.Drawing.Bitmap:.ctor (string)
(...)
Run Code Online (Sandbox Code Playgroud)
我尝试将单声道安装中的"libgdiplus.0.dylib"添加到包含的osx文件夹(单声道动态库也位于其中)和可执行文件夹中.除了更改错误消息中的文件名外,创建dllmap也不会执行任何操作.
我正在使用sgen变体,因此在x64中运行不是问题(另请参阅此处讨论此问题).
为了在不需要用户安装单声道框架的情况下分发我们的应用程序,我们使用MonoKickstart在运行时动态链接Mono库.我们正在使用Ionic.Zip库在应用程序启动时提取存档.默认情况下,此库使用IBM437编码.但是,它无法加载此编码,如以下异常所示:
System.NotSupportedException: No data is available for encoding 437.
at System.Text.Encoding.GetEncoding (Int32 codepage) <0x10a0d9970 + 0x0076e> in <filename unknown>:0
Run Code Online (Sandbox Code Playgroud)
此默认编码是静态初始化的,因此即使我们指定了不同的编码,仍会发生异常.
如果我们将I18N.dll和I18N.West.dll库包含到动态加载的库中,则会发生以下异常:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidProgramException: Invalid IL code in I18N.Common.Manager:get_PrimaryManager (): IL_0000: ret
at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) <0x11b3340e0 + 0x000bb> in <filename unknown>:0
--- End of inner exception stack trace ---
at System.Reflection.MonoMethod.Invoke (System.Object …Run Code Online (Sandbox Code Playgroud) 我是一名程序员,而且我很懒。目前,我正在使用C#中的一些OpenAL包装器。每次我调用OpenAL方法时,都必须使用OpenAL请求错误GetError,如果有错误,则会抛出异常。不久之后,我添加了一个包含以下功能的静态帮助器类:
public static void Check()
{
ALError error;
if ((error = AL.GetError()) != ALError.NoError)
throw new InvalidOperationException(AL.GetErrorString(error));
}
Run Code Online (Sandbox Code Playgroud)
这工作了一段时间,但我想要更多。因此,过了一会儿,我想出了以下方法:
public static void Call(Action function)
{
function();
ALHelper.Check();
}
public static void Call<TParameter>(Action<TParameter> function, TParameter parameter)
{
function(parameter);
ALHelper.Check();
}
public static TReturn Eval<TReturn>(Func<TReturn> function)
{
var val = function();
ALHelper.Check();
return val;
}
public static TReturn Eval<TParameter, TReturn>(Func<TParameter, TReturn> function, TParameter parameter)
{
var val = function(parameter);
ALHelper.Check();
return val;
}
Run Code Online (Sandbox Code Playgroud)
这很好用,但是我仍然对使用时的代码外观不满意,因此我决定将其进一步:将上述方法转换为扩展方法。据我所知,我可以将方法作为Action和Func参数传递,我认为它对于扩展方法同样适用,从而使丑陋的外观handles = …