假设我有一个声明如下的类:
public class ExampleClass
{
public Action<int> Do { get; set; }
public ExampleClass()
{
}
public void FuncA(int n)
{
//irrelevant code here
}
public void FuncB(int n)
{
//other irrelevant code here
}
}
我希望能够像这样使用这个类
ExampleClass excl = new ExampleClass() { Do = FuncA }
或
ExampleClass excl = new ExampleClass() { Do = excl.FuncA }
或
ExampleClass excl = new ExampleClass() { Do = ExampleClass.FuncA }
我可以在那里编译第二个选项,但是当我点击该代码时,我得到"Delegate to an instance method cannot have null 'this'."
异常。第三个甚至没有意义,因为FuncA不是静态的。
在我的实际代码中,可能有10-15种不同的功能可以绑定,我可以随时添加或删除它们,所以我不想要有一个大的开关或它 - 声明。另外,在实例化类时能够为'Do'赋值是非常方便的。
我只是使用不正确的语法?有没有更好的方法来创建一个类并在一行中分配一个动作?我应该只管理并管理一个巨大的转换声明吗?
答案 0 :(得分:3)
您必须创建该类的实例,然后将该属性设置为实例成员。类似的东西:
ExampleClass excl = new ExampleClass();
excl.Do = excl.FuncA;
对于你的专栏:
ExampleClass excl = new ExampleClass() { Do = FuncA }
没有该类的实例,FuncA不可见。
有关:
ExampleClass excl = new ExampleClass() { Do = excl.FuncA }
尚未创建实例,这就是您获得null引用的异常的原因。
有关:
ExampleClass excl = new ExampleClass() { Do = ExampleClass.FuncA }
FuncA
不是静态方法,您无法使用类名访问它。
答案 1 :(得分:2)
在对象初始值设定项语法中,您无法在明确赋值之前访问正在初始化的变量:
ExampleClass excl = new ExampleClass()
{
Do = excl.FuncA //excl is unavailable here
}
阅读Object and Collection Initializers (C# Programming Guide)了解详情。
您可以执行以下操作,例如:
public class ExampleClass
{
public Action<int> Do { get; set; }
public ExampleClass(bool useA)
{
if (useA)
Do = FuncA;
else
Do = FuncB;
}
public void FuncA(int n)
{
//irrelevant code here
}
public void FuncB(int n)
{
//other irrelevant code here
}
}
并使用它:
ExampleClass exclA = new ExampleClass(true);
ExampleClass exclB = new ExampleClass(false);
另一个想法是,如果这些函数可以声明为static
(即它们不需要ExampleClass
的任何实例成员),那么这将起作用:
public class ExampleClass
{
public Action<int> Do { get; set; }
public ExampleClass() { }
public static void FuncA(int n) { /*...*/}
public static void FuncB(int n) { /*...*/}
}
并按照您想要的方式使用它:
ExampleClass excl = new ExampleClass() { Do = ExampleClass.FuncA };
答案 2 :(得分:0)
如果您有扩展方法,请确保在调用扩展方法之前这些值不为null,或者在扩展方法中处理空值。
例如
public static ExtensionClass
{
public static bool RunExtensionMethod(this object myObject)
{
var someExecutionOnMyObject = myObject.IsValid();
//the above line would invoke the exception when myObject is null
return someExecutionOnMyObject ;
}
}
public void CallingMethod()
{
var myObject = getMyObject();
if(myObject.RunExtensionMethod()) //This would cause "delete to an instance method cannot have null" if myObject is null
{
}
}
要处理此场景,如果您拥有扩展类,则处理nulls并断言null。
public static ExtensionClass
{
public static bool RunExtensionMethod(this object myObject)
{
if(myObject == null) throw new ArgumentNullException(nameof(myObject));
var someExecutionOnMyObject = myObject.IsValid();
return someExecutionOnMyObject ;
}
}
public void CallingMethod()
{
var myObject = getMyObject();
if(myObject != null && myObject.RunExtensionMethod())
{
}
}