使用本地定义的类而不是库/包提供的类 C# IL Weaving
我见过像 Fody 这样的东西,实际上一直在使用 PropertyChanged 减少了实现 INotifyPropertyChanged 接口后的样板代码。
我相信这是通过“编织 IL”来完成的,所以我的脑海中闪过了一个想法。
问题是我试图定义我自己的类版本并使用它而不是 nuget 包中定义的版本。这是因为该库处理 TextView,而我希望它处理 AppCompatTextView。
AppCompatTextView 是:
public class AppCompatTextView :
TextView,
IEmojiCompatConfigurationView,
IJavaObject,
IDisposable,
IJavaPeerable,
ITintableBackgroundView,
IAutoSizeableTextView,
ITintableCompoundDrawablesView
如您所见,AppCompatTextView 继承自 TextView,这应该会让事情变得更容易。
默认情况下,库 (Xamarin.Forms) 已将 LabelRenderer 定义为:
public class LabelRenderer : FormsTextView, IVisualElementRenderer, IViewRenderer, ITabStop
其中:
namespace Xamarin.Forms.Platform.Android
{
public class FormsTextView : TextView
{
public FormsTextView(Context context) : base(context)
{
}
[Obsolete]
public FormsTextView(Context context, IAttributeSet attrs) : base(context, attrs)
{
}
[Obsolete]
public FormsTextView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
{
}
[Obsolete]
protected FormsTextView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
[Obsolete]
public void SkipNextInvalidate()
{
}
}
}
但是,我想创建自己的 LabelRenderer 版本,它继承自 AppCompatTextView。
这是为了满足 概述的要求Google 将显示现代表情符号
当看到 Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer 的代码时,我们可以看到:
protected global::Android.Widget.TextView Control => this;
我想到的想法是:可以使用一些 IL Weaving 工具,这样它就可以是这样的: 换句话说
protected global::AndroidX.AppCompat.Widget.AppCompatTextView Control => this;
,是否可以以某种方式“编织 IL”,以便当它想要加载此 IL 时:
.property instance class [Mono.Android]Android.Widget.TextView Control()
{
.get instance class [Mono.Android]Android.Widget.TextView Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer::get_Control()
}
它应该是一个 AndroidX.AppCompat.Widget .AppCompatTextView 而不是 Android.Widget.TextView:
.property instance class [Mono.Android]AndroidX.AppCompat.Widget.AppCompatTextView Control()
{
.get instance class [Mono.Android]AndroidX.AppCompat.Widget.AppCompatTextView Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer::get_Control()
} // end of property LabelRenderer::Control
谢谢!
I have seen stuff like Fody and in fact have been using PropertyChanged which reduces the boilerplate code after implementing the INotifyPropertyChanged interface.
I believe it is done by 'weaving the IL' so an idea crossed my mind.
The problem is that I am trying to define my own version of a class and use it instead of the one defined in a nuget package. This is because the library one deals with a TextView whereas I would like it to deal with an AppCompatTextView instead.
AppCompatTextView is:
public class AppCompatTextView :
TextView,
IEmojiCompatConfigurationView,
IJavaObject,
IDisposable,
IJavaPeerable,
ITintableBackgroundView,
IAutoSizeableTextView,
ITintableCompoundDrawablesView
As you can see, AppCompatTextView inherits from TextView and this should make things easier.
By default, the library (Xamarin.Forms) has defined a LabelRenderer as:
public class LabelRenderer : FormsTextView, IVisualElementRenderer, IViewRenderer, ITabStop
Where:
namespace Xamarin.Forms.Platform.Android
{
public class FormsTextView : TextView
{
public FormsTextView(Context context) : base(context)
{
}
[Obsolete]
public FormsTextView(Context context, IAttributeSet attrs) : base(context, attrs)
{
}
[Obsolete]
public FormsTextView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
{
}
[Obsolete]
protected FormsTextView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
[Obsolete]
public void SkipNextInvalidate()
{
}
}
}
However, I would like to create my own version of LabelRenderer which inherits from AppCompatTextView instead.
This is to meet the requirements outlined by Google to display modern emojis
When seeing the code for Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer, we can see that:
protected global::Android.Widget.TextView Control => this;
The idea that came to my mind was that would it be possible to use some IL Weaving tool so that it would be this instead:
protected global::AndroidX.AppCompat.Widget.AppCompatTextView Control => this;
In other words, would it be possible to 'weave the IL' in a way that when it wants to load this IL:
.property instance class [Mono.Android]Android.Widget.TextView Control()
{
.get instance class [Mono.Android]Android.Widget.TextView Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer::get_Control()
}
It should be an AndroidX.AppCompat.Widget.AppCompatTextView instead of Android.Widget.TextView:
.property instance class [Mono.Android]AndroidX.AppCompat.Widget.AppCompatTextView Control()
{
.get instance class [Mono.Android]AndroidX.AppCompat.Widget.AppCompatTextView Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer::get_Control()
} // end of property LabelRenderer::Control
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论