Return 泛型引用
Return reference of generic
我怎样才能实现这样的目标?
public class BlaBlaBla
{
private PotatoesContainer _containerField;
private bool _booleanField;
private ref T GetBackingFieldRef<T>(string propertyName)
{
if (string.IsNullOrWhiteSpace(propertyName))
throw new ArgumentNullException(nameof(propertyName));
if (propertyName == "BooleanProperty")
return ref _booleanField;
else if (propertyName == "ContainerProperty")
return ref _containerField;
throw new ArgumentException("Property does not exist", nameof(propertyName));
}
public void ManageProperty<T>(string propertyName, T newValue)
{
//Check stuff;
var referenceToField = GetBackingFieldRef<T>(propertyName);
referenceToField = newValue;
}
}
我搜索了所有 ref 文档,但没有看到任何内容。而且我无法调用 (T)
.
这可能吗?
是否有其他方法(使用 Action
、Func
或其他方法)?
如果您求助于使用不安全代码,这是可行的(大多数事情都是如此)。我同意评论者的观点,即这是一个 坏主意 并且有很多更好的方法可以实现您想要做的事情。然而,出于教育目的,无论如何,这里是:
using System.Runtime.CompilerServices;
...
public unsafe ref T GetBackingFieldRef<T>(string propertyName)
{
if (string.IsNullOrWhiteSpace(propertyName))
throw new ArgumentNullException(nameof(propertyName));
switch (propertyName)
{
case "BooleanProperty" when typeof(T) == typeof(bool):
return ref Unsafe.AsRef<T>(Unsafe.AsPointer(ref _booleanField));
case "ContainerProperty" when typeof(T) == typeof(PotatoesContainer):
return ref Unsafe.AsRef<T>(Unsafe.AsPointer(ref _containerField));
default:
throw new ArgumentException("Property does not exist or type mismatch", nameof(propertyName));
}
}
这使用 Unsafe.AsPointer<T>()
和 Unsafe.AsRef<T>()
来实现到 ref T
的其他困难转换。有一些类型检查以确保 T
的类型与支持字段的类型匹配,但这当然非常脆弱 - 如果您更改支持字段的类型,您必须记住更改类型检查,并且必须手动找到该字段对 GetBackingFieldRef<T>()
的所有调用并更新它们,否则您将在运行时出现异常 and/or 内存损坏。
我怎样才能实现这样的目标?
public class BlaBlaBla
{
private PotatoesContainer _containerField;
private bool _booleanField;
private ref T GetBackingFieldRef<T>(string propertyName)
{
if (string.IsNullOrWhiteSpace(propertyName))
throw new ArgumentNullException(nameof(propertyName));
if (propertyName == "BooleanProperty")
return ref _booleanField;
else if (propertyName == "ContainerProperty")
return ref _containerField;
throw new ArgumentException("Property does not exist", nameof(propertyName));
}
public void ManageProperty<T>(string propertyName, T newValue)
{
//Check stuff;
var referenceToField = GetBackingFieldRef<T>(propertyName);
referenceToField = newValue;
}
}
我搜索了所有 ref 文档,但没有看到任何内容。而且我无法调用 (T)
.
这可能吗?
是否有其他方法(使用 Action
、Func
或其他方法)?
如果您求助于使用不安全代码,这是可行的(大多数事情都是如此)。我同意评论者的观点,即这是一个 坏主意 并且有很多更好的方法可以实现您想要做的事情。然而,出于教育目的,无论如何,这里是:
using System.Runtime.CompilerServices;
...
public unsafe ref T GetBackingFieldRef<T>(string propertyName)
{
if (string.IsNullOrWhiteSpace(propertyName))
throw new ArgumentNullException(nameof(propertyName));
switch (propertyName)
{
case "BooleanProperty" when typeof(T) == typeof(bool):
return ref Unsafe.AsRef<T>(Unsafe.AsPointer(ref _booleanField));
case "ContainerProperty" when typeof(T) == typeof(PotatoesContainer):
return ref Unsafe.AsRef<T>(Unsafe.AsPointer(ref _containerField));
default:
throw new ArgumentException("Property does not exist or type mismatch", nameof(propertyName));
}
}
这使用 Unsafe.AsPointer<T>()
和 Unsafe.AsRef<T>()
来实现到 ref T
的其他困难转换。有一些类型检查以确保 T
的类型与支持字段的类型匹配,但这当然非常脆弱 - 如果您更改支持字段的类型,您必须记住更改类型检查,并且必须手动找到该字段对 GetBackingFieldRef<T>()
的所有调用并更新它们,否则您将在运行时出现异常 and/or 内存损坏。