我发现自己正在使用一个定义三个clases的库。类Element
和类ElementFile : Element
是第一个的子类,第三个类是Message
。
我一直在复制其他程序中的一些功能,作为如何使用前面提到的库的示例。这个程序是用VisualBasic编写的,但我们目前正在使用C#,所以我最终找到了一部分我不知道如何适应的代码。
在VisualBasic中,他们这样做:
Dim message As Message = library.NewMessage
Dim elem As New ElementFile("path")
message.addElement(elem)
由于我缺乏知识,我试图在C#中重现它:
Message message = library.NewMessage();
ElementFile elem = new ElementFile("path");
message.addElement(ref elem);
问题是方法addElement
期望第一个参数是Element
类型。
我使用JustDecompile检查库中此方法的声明,它看起来像这样:
public class Message
{
public void addElement(ref Element elem){ ... }
}
为什么addMethod
在VisualBasic中接受ElementFile
变量作为参数以及如何在C#中执行相同操作?如果VisualBasic代码有意义,有人可以确认一下吗?
答案 0 :(得分:3)
将声明的Element
类型更改为Element elem = new ElementFile("path");
message.addElement(ref elem);
,C#代码将编译:
ref Element e
Multi-project Builds - Gradle:e
表示“Element
必须是 ,您可以指定ElementFile
”的实例。对public void Test(ref Element e)
{
e = new Element();
}
的引用不符合该要求。
方法可以这样做:
Element
如果调用者中引用的引用属于ElementFile
类型,那就没问题。
如果我们被赋予对ElementFile e = new ElementFile();
// Nope.
e = new Element();
等派生类型的引用的引用,那就没有问题。然后我们会有效地做到这一点:
ref
如果我们只是添加一个约束,说该方法无法分配给它,那么它就不再是ref
:您可以通过省略ref
关键字在方法中实现该方法。
因此,编译器不允许您使用IList<ElementFile>
执行此操作。
这与你无法将IList<Element>
投射到IEnumerable<ElementFile>
的原因基本相同,但可以将IEnumerable<Element>
投射到bp = new BillingProcessor(this, LICENSE_KEY, MERCHANT_ID, new BillingProcessor.IBillingHandler() {
@Override
public void onProductPurchased(@NonNull String productId, @Nullable TransactionDetails details) {
showToast("onProductPurchased: " + productId);
updateTextViews();
}
@Override
public void onBillingError(int errorCode, @Nullable Throwable error) {
showToast("onBillingError: " + Integer.toString(errorCode));
}
@Override
public void onBillingInitialized() {
showToast("onBillingInitialized");
readyToPurchase = true;
updateTextViews();
}
@Override
public void onPurchaseHistoryRestored() {
showToast("onPurchaseHistoryRestored");
for(String sku : bp.listOwnedProducts())
Log.d(LOG_TAG, "Owned Managed Product: " + sku);
for(String sku : bp.listOwnedSubscriptions())
Log.d(LOG_TAG, "Owned Subscription: " + sku);
updateTextViews();
}
});
。
关于VB代码工作的原因,And here's why。 VB有一个明确的特例。
答案 1 :(得分:0)
如果你这样做(注意elem
的变量类型更改):
Message message = library.NewMessage();
Element elem = new ElementFile("path");
message.addElement(ref elem);