是否可以将对象创建限制为特定类的方法?
例如:我有一个类Transaction,我想将它的对象创建限制为继承自AbstractService或IService的任何类的方法:
允许的情景:
public class ServiceA : AbstractService (or IService)
{
public void MethodA()
{
var transaction = new Transaction();
}
public void MethodB()
{
var transaction = new Transaction();
}
}
禁止的情景:
public class ServiceB
{
public void MethodA()
{
var transaction = new Transaction(); // cannot create
}
public void MethodB()
{
var transaction = new Transaction(); // cannot create
}
}
我可以安装一个访问修饰符或其他东西吗?
答案 0 :(得分:2)
简短的回答是否定,没有访问修饰符说“此对象只能从实现特定接口的类构造”。
你可以围绕这个限制编写代码,但它远非干净/万无一失。
public class Transaction
{
private Transaction(){} // private important!
public static Transaction Create(object creator)
{
if(creator is IService)
return new Transaction();
throw new InvalidOperationException();
}
}
public class ServiceA : IService
{
public void MethodA()
{
var transaction = Transaction.Create(this); // works
}
}
public class ServiceB
{
public void MethodA()
{
var transaction = Transaction.Create(this); // fails
}
}
显而易见,以上是多么容易规避。我怀疑你有一个XY Problem并且认为这是解决问题的方法。
答案 1 :(得分:2)
我可以安装一个访问修饰符或其他东西吗?
是的其他可以" mount"那种情况,但在我看来,它的工作和抽象很少,很少有奖励。这需要返回Transaction的接口,而不是具体类型。 (我很确定这有效,但我还没有编译它。)
public abstract class AbstractService
{
}
public interface IService
{
}
public interface ITransaction
{
}
public static class TransactionFactory
{
// created them as extensions, but you could remove *this*
public static ITransaction CreateTransaction(this AbstractService instance)
{
return new Transaction ();
}
public static ITransaction CreateTransaction(this IService instance)
{
return new Transaction ();
}
private class Transaction : ITransaction
{
public Transaction ()
{
}
}
}
作为旁注,某人在技术上可以传递 null ,因此最好对方法参数进行额外检查(但是,这将是运行时问题而不是编译时问题)。
如果你想编译时检查,我认为你可以做...
public interface ITransactionFactory { }
public abstract class AbstractService : ITransactionFactory { }
public interface IService : ITransactionFactory { }
public static class TransactionFactory<T>
where T : ITransactionFactory
{
public static ITransaction CreateTransaction(this T instance)
{
return new Transaction ();
}
// ....
不太确定第二个是否正常工作
答案 2 :(得分:2)
也许我误解了你想要做的事情,但看起来这应该可以解决问题:
public abstract class AbstractService : IService
{
protected class Transaction
{
}
}
public class ServiceA : AbstractService
{
public void MethodA()
{
var transaction = new Transaction();
}
public void MethodB()
{
var transaction = new Transaction();
}
}
public class ServiceB
{
public void MethodA()
{
var transaction = new Transaction(); // cannot create
}
public void MethodB()
{
var transaction = new Transaction(); // cannot create
}
}
internal interface IService
{
}
如果您希望其他任何人能够使用Transaction
,您需要让它实现一些公共接口或从其他公共类继承它,但您现在可以确保没有其他人可以创建一个Transaction对象。