C#、WinForms 和扩展方法
问题
除了所有明显的答案之外,什么会导致扩展方法生成如下所示的编译器错误:
'DataType' 不包含 'YourExtensionMethodName' 的定义
I'这里有一个真正的难题,下面为您详细说明。我已经用尽了所有我能想到的可能原因。
场景
- 我在由 WinForms 应用程序使用的 DLL 中的各种静态类中定义了几个扩展方法。
- 扩展方法签名与我正在扩展的类上的方法签名(在本例中为
String
)不冲突。 - DLL 和 WinForms 应用程序都是用 C# 编写的。
- DLL 和 WinForms 应用程序都配置为面向 .NET 3.5。
- 使用类包含对定义扩展方法的命名空间的引用。其拼写已被验证。
- 如果我直接引用扩展类,则会出现扩展方法。例如,如果我输入
StringExtensions.
,Intellisense 将正常显示,并列出我的所有扩展方法。 - 编辑:错误发生在 WinForms 应用程序中,但仅针对某些扩展方法,而不是全部。
代码(或其摘录)
(是的,这是有问题的代码)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Roswell.Framework
{
public static class StringBuilderExtensions
{
public static string ToSentenceCase(this string value)
{
return value.Substring(0, 1).ToUpper() + value.Substring(1).ToLower();
}
public static string ToTitleCase(this string value)
{
string[] parts = value.Split(new string[] {" "}, StringSplitOptions.None);
System.Text.StringBuilder builder = new System.Text.StringBuilder();
foreach (string part in parts)
{
builder.Append(part.ToSentenceCase());
builder.Append(" ");
}
return builder.ToString();
}
}
}
这是使用它的代码:
using Roswell.Framework;
namespace Roswell.Windows.Command
{
/// <summary>
/// Views the SQL for an object in the database window.
/// </summary>
internal class ViewObjectDdlCommand
: MainWindowCommand
{
public override void Execute()
{
// ...
OpenCodeWindow(
string.Format("{0} - {1} - {2}",
dsn.Name,
objectName,
info.ToTitleCase()),
schemaItemType,
objectName);
}
}
}
The Question
Aside from all the obvious answers, what would cause extension methods to generate compiler errors like this one:
'DataType' does not contain a definition for 'YourExtensionMethodName'
I've got a real stumper here, and it's spelled out for you in detail below. I've exhausted all the possible causes I can think of.
Scenario
- I have a couple of extension methods defined in various static classes in a DLL that is consumed by a WinForms application.
- The extension method signatures do not conflict with the signatures of methods on the class I'm extending (
String
, in this case). - Both the DLL and the WinForms application are written in C#.
- Both the DLL and the WinForms application are configured to target .NET 3.5.
- The consuming classes include a reference to the namespace that defines the extension method. Its spelling has been verified.
- If I reference the extension class directly, the extension methods appear. For example, if I type
StringExtensions.
, Intellisense appears as normal, with all of my extension methods listed. - EDIT: The errors are occurring in the WinForms application, but only for some of the extension methods, not all of them.
The Code (Or an Excerpt Thereof)
(Yep, this is the offending code)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Roswell.Framework
{
public static class StringBuilderExtensions
{
public static string ToSentenceCase(this string value)
{
return value.Substring(0, 1).ToUpper() + value.Substring(1).ToLower();
}
public static string ToTitleCase(this string value)
{
string[] parts = value.Split(new string[] {" "}, StringSplitOptions.None);
System.Text.StringBuilder builder = new System.Text.StringBuilder();
foreach (string part in parts)
{
builder.Append(part.ToSentenceCase());
builder.Append(" ");
}
return builder.ToString();
}
}
}
And this is the code that consumes it:
using Roswell.Framework;
namespace Roswell.Windows.Command
{
/// <summary>
/// Views the SQL for an object in the database window.
/// </summary>
internal class ViewObjectDdlCommand
: MainWindowCommand
{
public override void Execute()
{
// ...
OpenCodeWindow(
string.Format("{0} - {1} - {2}",
dsn.Name,
objectName,
info.ToTitleCase()),
schemaItemType,
objectName);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从您的代码片段中,我可以看到您正在对名为
info
的内容调用ToTitleCase
。但我看不到该变量的类型,这将决定这里发生的情况。显然它必须是一个字符串(如果字符串不是密封类,它可能是从字符串派生的东西,但这对于密封类来说是不可能的)。
因此,唯一有意义的事情(除了极不可能的编译器错误)是
info
不是字符串。From your code snippet, I can see you're calling
ToTitleCase
on something calledinfo
. But I can't see the type of that variable, which is the thing that will determine what is happening here.Obviously it needs to be a string (if string was not a sealed class it could be something derived from string, but that's impossible for a sealed class).
So the only thing that makes sense (aside from a very unlikely compiler error) is that
info
is not a string.该错误提示了答案:
在这种情况下,我的猜测是“info” (
ViewObjectDdlCommand.info
) 不是字符串,而是 DataType。尝试将其更改为:The error suggests the answer:
In this case, my guess is that "info" (
ViewObjectDdlCommand.info
) is not a string, but rather DataType. Try changing it to: